﻿using System;
using System.Collections.Generic;
using System.Text;

using RaisingStudio.Data.Common;
using RaisingStudio.Data.Common.Factories;
using RaisingStudio.Data.Expressions;
using RaisingStudio.Data.Common.Builders.Expressions;
using RaisingStudio.Data.Common.Managers;
using System.Data.Common;
using RaisingStudio.Data.Providers.Exceptions;
using System.Data;

namespace RaisingStudio.Data.Providers.Adapters
{
    public delegate object CreateDataObjectDelegate();
    public delegate System.Collections.IList CreateDataObjectListDelegate();

    /// <summary>
    /// data object DataAdapter.
    /// </summary>
    public partial class DataObjectAdapter : DataAdapterBase, RaisingStudio.Data.Common.IDataObjectAdapter
    {
        #region Common property
        protected System.Type dataObjectType;
        /// <summary>
        /// Type of data object.
        /// </summary>
        public System.Type DataObjectType
        {
            get
            {
                return this.dataObjectType;
            }
        }

        protected string definitionName;
        /// <summary>
        /// object definition name.
        /// </summary>
        public string DefinitionName
        {
            get
            {
                return this.definitionName;
            }
        }


        protected RaisingStudio.Data.Common.Builders.CommandBuilder commandBuilder;
        /// <summary>
        /// Command builder.
        /// </summary>
        public RaisingStudio.Data.Common.Builders.CommandBuilder CommandBuilder
        {
            get
            {
                if (this.commandBuilder == null)
                {
                    this.commandBuilder = CreateCommandBuilder();
                }
                return this.commandBuilder;
            }
        }

        protected System.Data.Common.DataTableMapping defaultDataTableMapping;
        /// <summary>
        /// default Data table mapping.
        /// </summary>
        public System.Data.Common.DataTableMapping DefaultDataTableMapping
        {
            get
            {
                if (this.defaultDataTableMapping == null)
                {
                    this.defaultDataTableMapping = this.CommandBuilder.CommonCommandBuilder.GetDataTableMapping();
                }
                return this.defaultDataTableMapping;
            }
        }
        #endregion
#if (PocketPC || Smartphone || WindowsCE)
        private bool _useDynamicProxy = false;
#else
        private bool _useDynamicProxy = true;
#endif
        public bool UseDynamicProxy
        {
            get { return _useDynamicProxy; }
            set { _useDynamicProxy = value; }
        }

        private bool _cacheDefalutCommand = true;

        public bool CacheDefalutCommand
        {
            get { return _cacheDefalutCommand; }
            set { _cacheDefalutCommand = value; }
        }

        #region Constructor
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="dataObjectType">Type of data object.</param>
        public DataObjectAdapter(System.Type dataObjectType)
        {
            this.dataObjectType = dataObjectType;
            this.connection = ConnectionFactory.CreateConnection();
            DatabaseType databaseType;
            string providerName;
            ConnectionFactory.GetConnectionSetting(out databaseType, out providerName);
            this._databaseType = databaseType;
            this._providerName = providerName;
            this.transactionManager = TransactionManagerFactory.CreateTransactionManager(this.connection);
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="dataObjectType">Type of data object.</param>
        /// <param name="connection">database connection.</param>
        public DataObjectAdapter(System.Type dataObjectType, System.Data.IDbConnection connection)
        {
            this.dataObjectType = dataObjectType;
            this.connection = connection;
            this.transactionManager = TransactionManagerFactory.CreateTransactionManager(this.connection);
        }

        public DataObjectAdapter(System.Type dataObjectType, System.Data.IDbConnection connection, DatabaseType databaseType, string providerName)
            : this(dataObjectType, connection)
        {
            this._databaseType = databaseType;
            this._providerName = providerName;
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="dataObjectType">Type of data object.</param>
        /// <param name="transactionManager">database transaction manager.</param>
        public DataObjectAdapter(System.Type dataObjectType, TransactionManager transactionManager, ILogManager logManager)
        {
            this.dataObjectType = dataObjectType;
            this.transactionManager = transactionManager;
            this.connection = transactionManager.Connection;
            this._logManager = logManager;
        }

        public DataObjectAdapter(System.Type dataObjectType, TransactionManager transactionManager, DatabaseType databaseType, string providerName, ILogManager logManager)
            : this(dataObjectType, transactionManager, logManager)
        {
            this._databaseType = databaseType;
            this._providerName = providerName;
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="dataObjectType">Type of data object.</param>
        /// <param name="definitionName">object definition name.</param>
        public DataObjectAdapter(System.Type dataObjectType, string definitionName)
            : this(dataObjectType)
        {
            this.definitionName = definitionName;
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="dataObjectType">Type of data object.</param>
        /// <param name="definitionName">object definition name.</param>
        /// <param name="connection">database connection.</param>
        public DataObjectAdapter(System.Type dataObjectType, string definitionName, System.Data.IDbConnection connection)
            : this(dataObjectType, connection)
        {
            this.definitionName = definitionName;
        }

        public DataObjectAdapter(System.Type dataObjectType, string definitionName, System.Data.IDbConnection connection, DatabaseType databaseType, string providerName)
            : this(dataObjectType, definitionName, connection)
        {
            this._databaseType = databaseType;
            this._providerName = providerName;
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="dataObjectType">Type of data object.</param>
        /// <param name="definitionName">object definition name.</param>
        /// <param name="transactionManager">database transaction manager.</param>
        public DataObjectAdapter(System.Type dataObjectType, string definitionName, TransactionManager transactionManager, ILogManager logManager)
            : this(dataObjectType, transactionManager, logManager)
        {
            this.definitionName = definitionName;
        }

        public DataObjectAdapter(System.Type dataObjectType, string definitionName, TransactionManager transactionManager, DatabaseType databaseType, string providerName, ILogManager logManager)
            : this(dataObjectType, definitionName, transactionManager, logManager)
        {
            this._databaseType = databaseType;
            this._providerName = providerName;
        }
        #endregion

        #region Create Command
        /// <summary>
        /// Create a command builder.
        /// </summary>
        /// <returns>Command builder.</returns>
        public virtual RaisingStudio.Data.Common.Builders.CommandBuilder CreateCommandBuilder()
        {
            DatabaseType databaseType = GetDatabaseType();
#if !(PocketPC || Smartphone || WindowsCE)
            if (databaseType == DatabaseType.SHAREPOINT)
            {
                if (this.definitionName != null)
                {
                    return new RaisingStudio.Data.Common.Builders.SharePointCommandBuilder(this.connection, databaseType, this._providerName, this.dataObjectType, this.definitionName);
                }
                else
                {
                    return new RaisingStudio.Data.Common.Builders.SharePointCommandBuilder(this.connection, databaseType, this._providerName, this.dataObjectType);
                }
            }
            else
            {
#endif
                if (this.definitionName != null)
                {
                    return new RaisingStudio.Data.Common.Builders.CommandBuilder(this.connection, databaseType, this._providerName, this.dataObjectType, this.definitionName);
                }
                else
                {
                    return new RaisingStudio.Data.Common.Builders.CommandBuilder(this.connection, databaseType, this._providerName, this.dataObjectType);
                }
#if !(PocketPC || Smartphone || WindowsCE)
            }
#endif
        }

        public virtual DatabaseType GetDatabaseType()
        {
            if ((this._databaseType == DatabaseType.OTHER) && (!ProviderManager.Instance.ProviderExists(this._providerName)))
            {
                DatabaseType databaseType = ConnectionFactory.GetDatabaseType(this.connection);
                return databaseType;
            }
            return this._databaseType;
        }
        #endregion
        #region Create data object
        protected CreateDataObjectDelegate createDataObjectMethod;
        /// <summary>
        /// Create data object delegate.
        /// </summary>
        public CreateDataObjectDelegate CreateDataObjectMethod
        {
            get
            {
                return this.createDataObjectMethod;
            }
            set
            {
                this.createDataObjectMethod = value;
            }
        }

        /// <summary>
        /// Create Data object.
        /// </summary>
        /// <returns>Data object.</returns>
        public virtual object CreateDataObject()
        {
            if (this.createDataObjectMethod != null)
            {
                return this.createDataObjectMethod();
            }
            else
            {
                if (UseDynamicProxy)
                {
                    #region UseDynamicProxy
                    IObjectCreater objectCreater = GetObjectCreater(dataObjectType, this.CommandBuilder.CommonCommandBuilder.DataTableDefinition.Columns);
                    if (objectCreater != null)
                    {
                        object dataObject = objectCreater.CreateObject();
                        return dataObject;
                    }
                    else
                    {
                        // TODO: exception.
                        #region Reflection
                        object dataObject = System.Activator.CreateInstance(this.dataObjectType);
                        return dataObject;
                        #endregion
                    }
                    #endregion
                }
                else
                {
                    #region Reflection
                    object dataObject = System.Activator.CreateInstance(this.dataObjectType);
                    return dataObject;
                    #endregion
                }
            }
        }

        protected CreateDataObjectListDelegate createDataObjectListMethod;
        /// <summary>
        /// Create data object column table delegate.
        /// </summary>
        public CreateDataObjectListDelegate CreateDataObjectListMethod
        {
            get
            {
                return this.createDataObjectListMethod;
            }
            set
            {
                this.createDataObjectListMethod = value;
            }
        }

        /// <summary>
        /// Create data object column table.
        /// </summary>
        /// <returns>data object column table.</returns>
        public virtual System.Collections.IList CreateDataObjectList()
        {
            if (this.createDataObjectListMethod != null)
            {
                return this.createDataObjectListMethod();
            }
            else
            {
                if (UseDynamicProxy)
                {
                    #region UseDynamicProxy
                    IObjectCreater objectCreater = GetObjectCreater(dataObjectType, this.CommandBuilder.CommonCommandBuilder.DataTableDefinition.Columns);
                    if (objectCreater != null)
                    {
                        System.Collections.IList dataObjectList = objectCreater.CreateObjectList();
                        return dataObjectList;
                    }
                    else
                    {
                        // TODO: exception.
                        #region Reflection
                        System.Type listType = typeof(List<>);
                        System.Type dataObjectListType = listType.MakeGenericType(this.dataObjectType);
                        System.Collections.IList dataObjectList = System.Activator.CreateInstance(dataObjectListType) as System.Collections.IList;
                        return dataObjectList;
                        #endregion
                    }
                    #endregion
                }
                else
                {
                    #region Reflection
                    System.Type listType = typeof(List<>);
                    System.Type dataObjectListType = listType.MakeGenericType(this.dataObjectType);
                    System.Collections.IList dataObjectList = System.Activator.CreateInstance(dataObjectListType) as System.Collections.IList;
                    return dataObjectList;
                    #endregion
                }
            }
        }
        #endregion

        #region Transactions
        /// <summary>
        /// Begin Database transaction.
        /// </summary>
        /// <returns>The ID of transaction.</returns>
        public virtual string BeginTransaction()
        {
            return this.transactionManager.BeginTransaction();
        }

        /// <summary>
        /// Begin Database transaction.
        /// </summary>
        /// <param name="isolationLevel">Specifies the isolation level for the transaction.</param>
        /// <returns>The ID of transaction.</returns>
        public virtual string BeginTransaction(System.Data.IsolationLevel isolationLevel)
        {
            return this.transactionManager.BeginTransaction(isolationLevel);
        }

        /// <summary>
        /// Commit Database transaction.
        /// </summary>
        public virtual void CommitTransaction()
        {
            this.transactionManager.CommitTransaction();
        }

        /// <summary>
        /// Commit Database transaction.
        /// </summary>
        /// <param name="transactionID">The ID of transaction.</param>
        public virtual void CommitTransaction(string transactionID)
        {
            this.transactionManager.CommitTransaction(transactionID);
        }

        /// <summary>
        /// Rollback transaction.
        /// </summary>
        public virtual void RollbackTransaction()
        {
            this.transactionManager.RollbackTransaction();
        }

        /// <summary>
        /// Rollback transaction.
        /// </summary>
        /// <param name="transactionID">The ID of transaction.</param>
        public virtual void RollbackTransaction(string transactionID)
        {
            this.transactionManager.RollbackTransaction(transactionID);
        }
        #endregion

        #region Gets primary key value
        /// <summary>
        /// Gets data object The value of primary key.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <returns>The value of primary key.</returns>
        public virtual object[] GetPrimaryKeys(object dataObject)
        {
            object[] primaryKeys = new object[this.CommandBuilder.CommonCommandBuilder.DataTableDefinition.PrimaryKeys.Count];
            if (UseDynamicProxy)
            {
                #region UseDynamicProxy
                System.Type dataObjectType = dataObject.GetType();
                IObjectAccessor objectAccessor = GetObjectAccessor(dataObjectType, this.CommandBuilder.CommonCommandBuilder.DataTableDefinition.Columns);
                if (objectAccessor != null)
                {
                    for (int i = 0; i < this.CommandBuilder.CommonCommandBuilder.DataTableDefinition.PrimaryKeys.Count; i++)
                    {
                        string columnName = this.CommandBuilder.CommonCommandBuilder.DataTableDefinition.PrimaryKeys[i];
                        primaryKeys[i] = objectAccessor.GetValue(dataObject, columnName);
                    }
                }
                else
                {
                    // TODO: exception.
                    throw new ObjectAccessorException(string.Format("Can't get ObjectAccessor for type [{0}].", dataObjectType));
                }
                #endregion
            }
            else
            {
                if (dataObject is IObjectAccessor)
                {
                    #region IObjectAccessor
                    IObjectAccessor objectAccessor = dataObject as IObjectAccessor;
                    if (objectAccessor != null)
                    {
                        for (int i = 0; i < this.CommandBuilder.CommonCommandBuilder.DataTableDefinition.PrimaryKeys.Count; i++)
                        {
                            string columnName = this.CommandBuilder.CommonCommandBuilder.DataTableDefinition.PrimaryKeys[i];
                            primaryKeys[i] = objectAccessor.GetValue(dataObject, columnName);
                        }
                    }
                    #endregion
                }
                else
                {
                    #region Reflection
                    System.Type dataObjectType = dataObject.GetType();
                    for (int i = 0; i < this.CommandBuilder.CommonCommandBuilder.DataTableDefinition.PrimaryKeys.Count; i++)
                    {
                        string columnName = this.CommandBuilder.CommonCommandBuilder.DataTableDefinition.PrimaryKeys[i];
                        System.Reflection.PropertyInfo propertyInfo = dataObjectType.GetProperty(columnName);
                        if (propertyInfo != null)
                        {
                            primaryKeys[i] = propertyInfo.GetValue(dataObject, null);
                        }
                        else
                        {
                            throw new System.MissingMemberException(string.Format("Can not find a property named {1} in type  {0}.", dataObjectType, columnName));
                        }
                    }
                    #endregion
                }
            }
            return primaryKeys;
        }

        private IObjectCreater GetObjectCreater(Type dataObjectType, Dictionary<string, DataColumnDefinition> columns)
        {
            return ObjectAccessorManager.Instance.GetObjectAccessor(dataObjectType, columns) as IObjectCreater;
        }

        private IObjectAccessor GetObjectAccessor(Type dataObjectType, Dictionary<string, DataColumnDefinition> columns)
        {
            return ObjectAccessorManager.Instance.GetObjectAccessor(dataObjectType, columns);
        }

        private IObjectAccessor GetObjectAccessor(Type dataObjectType, DataColumnMappingCollection columnMappings)
        {
            return ObjectAccessorManager.Instance.GetObjectAccessor(dataObjectType, columnMappings);
        }

        private Type GetDataObjectPropertyType(Type dataObjectType, string propertyName)
        {
            return ObjectAccessorManager.Instance.GetPropertyType(dataObjectType, propertyName);
        }
        #endregion

        public void SetParameterValue(object parameter, object value)
        {
            // TODO: convert.
            (parameter as System.Data.IDbDataParameter).Value = value;
        }

        #region protected methods
        /// <summary>
        /// FillData item.
        /// </summary>
        /// <param name="command">Command.</param>
        /// <param name="dataTableMapping">Data table mapping.</param>
        /// <param name="dataObject">Data object.</param>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>The result of execute command.</returns>
        protected int Fill(System.Data.IDbCommand command, System.Data.Common.DataTableMapping dataTableMapping, object dataObject, object[] primaryKeys, System.Data.IDbTransaction transaction)
        {
            for (int i = 0; i < command.Parameters.Count; i++)
            {
                SetParameterValue(command.Parameters[i], primaryKeys[i]);
            }
            if (transaction != null)
            {
                command.Transaction = transaction;
            }
            WriteLog(command);
            System.Data.IDataReader dataReader = RaisingStudio.Data.Common.Database.ExecuteReaderCommand(command);
            try
            {
                if (dataReader.Read())
                {
                    if (UseDynamicProxy)
                    {
                        #region UseDynamicProxy
                        System.Type dataObjectType = dataObject.GetType();
                        IObjectAccessor objectAccessor = GetObjectAccessor(dataObjectType, this.CommandBuilder.CommonCommandBuilder.DataTableDefinition.Columns);
                        SetDataObjectValues(dataReader, dataTableMapping, dataObjectType, objectAccessor, dataObject);
                        #endregion
                    }
                    else
                    {
                        if (dataObject is IDataObjectProxy)
                        {
                            #region IObjectAccessor
                            SetDataObjectValues(dataReader, dataTableMapping, dataObject as IDataObjectProxy, dataObject);
                            #endregion
                        }
                        else
                        {
                            #region Reflection
                            System.Type dataObjectType = dataObject.GetType();
                            SetDataObjectValues(dataReader, dataTableMapping, dataObjectType, dataObject);
                            #endregion
                        }
                    }
                }
            }
            finally
            {
                if (dataReader != null)
                {
                    dataReader.Close();
                }
            }

            return dataReader.RecordsAffected;
        }


        private void SetDataObjectValues(System.Data.IDataReader dataReader, System.Data.Common.DataTableMapping dataTableMapping, System.Type dataObjectType, IObjectAccessor objectAccessor, object dataObject)
        {
            if (objectAccessor != null)
            {
                foreach (System.Data.Common.DataColumnMapping dataColumnMapping in dataTableMapping.ColumnMappings)
                {
                    string columnName = dataColumnMapping.DataSetColumn;
                    string sourceName = dataColumnMapping.SourceColumn;
                    DataColumnDefinition dataColumnDefinition = this.CommandBuilder.CommonCommandBuilder.DataTableDefinition.Columns[columnName];
                    System.Data.DbType dbType = dataColumnDefinition.DbType;
                    object value = DataItemAdapter.GetDataReaderValue(dataReader, sourceName, dbType);
                    if (value == System.DBNull.Value)
                    {
                        objectAccessor.SetValue(dataObject, columnName, null);
                    }
                    else
                    {
                        Type propertyType = GetDataObjectPropertyType(dataObjectType, columnName);
                        value = ConvertDataValue(dbType, propertyType, value);
                        objectAccessor.SetValue(dataObject, columnName, value);
                    }
                }
            }
            else
            {
                // TODO: exception.
                throw new ObjectAccessorException(string.Format("Can't get ObjectAccessor for type [{0}].", dataObjectType));
            }
        }

        private void SetDataObjectValues(System.Data.IDataReader dataReader, System.Data.Common.DataTableMapping dataTableMapping, IDataObjectProxy proxy, object dataObject)
        {
            if (proxy != null)
            {
                foreach (System.Data.Common.DataColumnMapping dataColumnMapping in dataTableMapping.ColumnMappings)
                {
                    string columnName = dataColumnMapping.DataSetColumn;
                    string sourceName = dataColumnMapping.SourceColumn;
                    DataColumnDefinition dataColumnDefinition = this.CommandBuilder.CommonCommandBuilder.DataTableDefinition.Columns[columnName];
                    System.Data.DbType dbType = dataColumnDefinition.DbType;
                    object value = DataItemAdapter.GetDataReaderValue(dataReader, sourceName, dbType);
                    if (value == System.DBNull.Value)
                    {
                        proxy.SetValue(dataObject, columnName, null);
                    }
                    else
                    {
                        Type propertyType = proxy.GetPropertyType(columnName);
                        value = ConvertDataValue(dbType, propertyType, value);
                        proxy.SetValue(dataObject, columnName, value);
                    }
                }
            }
            else
            {
                // TODO: exception.
                throw new ObjectAccessorException(string.Format("Can't get ObjectAccessor for type [{0}].", dataObjectType));
            }
        }

        private void SetDataObjectValues(System.Data.IDataReader dataReader, System.Data.Common.DataTableMapping dataTableMapping, System.Type dataObjectType, object dataObject)
        {
            foreach (System.Data.Common.DataColumnMapping dataColumnMapping in dataTableMapping.ColumnMappings)
            {
                string columnName = dataColumnMapping.DataSetColumn;
                string sourceName = dataColumnMapping.SourceColumn;
                DataColumnDefinition dataColumnDefinition = this.CommandBuilder.CommonCommandBuilder.DataTableDefinition.Columns[columnName];
                System.Data.DbType dbType = dataColumnDefinition.DbType;
                System.Reflection.PropertyInfo propertyInfo = dataObjectType.GetProperty(columnName);
                if (propertyInfo != null)
                {
                    object value = DataItemAdapter.GetDataReaderValue(dataReader, sourceName, dbType);
                    if (value == System.DBNull.Value)
                    {
                        propertyInfo.SetValue(dataObject, null, null);
                    }
                    else
                    {
                        value = ConvertDataValue(dbType, propertyInfo.PropertyType, value);
                        propertyInfo.SetValue(dataObject, value, null);
                    }
                }
                else
                {
                    throw new System.MissingMemberException(string.Format("Can not find a property named {1} in type  {0}.", dataObjectType, columnName));
                }
            }
        }


        private object ConvertDataValue(System.Data.DbType dbType, Type propertyType, object value)
        {
            return ConverterManager.ConvertDataValue(dbType, propertyType, value);
        }

        private object ConvertDataValue(Type propertyType, System.Data.DbType dbType, object value)
        {
            return ConverterManager.ConvertDataValue(propertyType, dbType, value);
        }

        /// <summary>
        /// FillData item.
        /// </summary>
        /// <param name="command">Command.</param>
        /// <param name="dataTableMapping">Data table mapping.</param>
        /// <param name="dataObject">Data object.</param>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>The result of execute command.</returns>
        protected int Fill(System.Data.IDbCommand command, System.Data.Common.DataTableMapping dataTableMapping, object dataObject, object[] primaryKeys, string[] columnNames, System.Data.IDbTransaction transaction)
        {
            for (int i = 0; i < command.Parameters.Count; i++)
            {
                SetParameterValue(command.Parameters[i], primaryKeys[i]);
            }
            if (transaction != null)
            {
                command.Transaction = transaction;
            }
            WriteLog(command);
            System.Data.IDataReader dataReader = RaisingStudio.Data.Common.Database.ExecuteReaderCommand(command);
            try
            {
                if (dataReader.Read())
                {
                    if (UseDynamicProxy)
                    {
                        #region UseDynamicProxy
                        System.Type dataObjectType = dataObject.GetType();
                        IObjectAccessor objectAccessor = GetObjectAccessor(dataObjectType, this.CommandBuilder.CommonCommandBuilder.DataTableDefinition.Columns);
                        SetDataObjectValues(dataTableMapping, dataObject, columnNames, dataReader, dataObjectType, objectAccessor);
                        #endregion
                    }
                    else
                    {
                        if (dataObject is IDataObjectProxy)
                        {
                            #region IObjectAccessor
                            IObjectAccessor objectAccessor = dataObject as IObjectAccessor;
                            SetDataObjectValues(dataTableMapping, dataObject, columnNames, dataReader, dataObject as IDataObjectProxy, objectAccessor);
                            #endregion
                        }
                        else
                        {
                            #region Reflection
                            System.Type dataObjectType = dataObject.GetType();
                            SetDataObjectValues(dataTableMapping, dataObject, columnNames, dataReader, dataObjectType);
                            #endregion
                        }
                    }
                }
            }
            finally
            {
                if (dataReader != null)
                {
                    dataReader.Close();
                }
            }

            return dataReader.RecordsAffected;
        }


        private void SetDataObjectValues(System.Data.Common.DataTableMapping dataTableMapping, object dataObject, string[] columnNames, System.Data.IDataReader dataReader, System.Type dataObjectType, IObjectAccessor objectAccessor)
        {
            if (objectAccessor != null)
            {
                foreach (string columnName in columnNames)
                {
                    DataColumnDefinition dataColumnDefinition = this.CommandBuilder.CommonCommandBuilder.DataTableDefinition.Columns[columnName];
                    string sourceName = RaisingStudio.Data.Common.Builders.CommonCommandBuilder.GetDataColumnSourceColumn(dataTableMapping, columnName);
                    System.Data.DbType dbType = dataColumnDefinition.DbType;
                    object value = DataItemAdapter.GetDataReaderValue(dataReader, sourceName, dbType);
                    if (value == System.DBNull.Value)
                    {
                        objectAccessor.SetValue(dataObject, columnName, null);
                    }
                    else
                    {
                        Type propertyType = GetDataObjectPropertyType(dataObjectType, columnName);
                        value = ConvertDataValue(dbType, propertyType, value);
                        objectAccessor.SetValue(dataObject, columnName, value);
                    }
                }
            }
            else
            {
                // TODO: exception.
                throw new ObjectAccessorException(string.Format("Can't get ObjectAccessor for type [{0}].", dataObjectType));
            }
        }
        
        private void SetDataObjectValues(System.Data.Common.DataTableMapping dataTableMapping, object dataObject, string[] columnNames, System.Data.IDataReader dataReader, IDataObjectProxy proxy, IObjectAccessor objectAccessor)
        {
            if (objectAccessor != null)
            {
                foreach (string columnName in columnNames)
                {
                    DataColumnDefinition dataColumnDefinition = this.CommandBuilder.CommonCommandBuilder.DataTableDefinition.Columns[columnName];
                    string sourceName = RaisingStudio.Data.Common.Builders.CommonCommandBuilder.GetDataColumnSourceColumn(dataTableMapping, columnName);
                    System.Data.DbType dbType = dataColumnDefinition.DbType;
                    object value = DataItemAdapter.GetDataReaderValue(dataReader, sourceName, dbType);
                    if (value == System.DBNull.Value)
                    {
                        objectAccessor.SetValue(dataObject, columnName, null);
                    }
                    else
                    {
                        Type propertyType = proxy.GetPropertyType(columnName);
                        value = ConvertDataValue(dbType, propertyType, value);
                        objectAccessor.SetValue(dataObject, columnName, value);
                    }
                }
            }
            else
            {
                // TODO: exception.
                throw new ObjectAccessorException(string.Format("Can't get ObjectAccessor for type [{0}].", dataObjectType));
            }
        }

        private void SetDataObjectValues(System.Data.Common.DataTableMapping dataTableMapping, object dataObject, string[] columnNames, System.Data.IDataReader dataReader, System.Type dataObjectType)
        {
            foreach (string columnName in columnNames)
            {
                DataColumnDefinition dataColumnDefinition = this.CommandBuilder.CommonCommandBuilder.DataTableDefinition.Columns[columnName];
                string sourceName = RaisingStudio.Data.Common.Builders.CommonCommandBuilder.GetDataColumnSourceColumn(dataTableMapping, columnName);
                System.Data.DbType dbType = dataColumnDefinition.DbType;

                System.Reflection.PropertyInfo propertyInfo = dataObjectType.GetProperty(columnName);
                if (propertyInfo != null)
                {
                    object value = DataItemAdapter.GetDataReaderValue(dataReader, sourceName, dbType);
                    if (value == System.DBNull.Value)
                    {
                        propertyInfo.SetValue(dataObject, null, null);
                    }
                    else
                    {
                        value = ConvertDataValue(dbType, propertyInfo.PropertyType, value);
                        propertyInfo.SetValue(dataObject, value, null);
                    }
                }
                else
                {
                    throw new System.MissingMemberException(string.Format("Can not find a property named {1} in type  {0}.", dataObjectType, columnName));
                }
            }
        }

        private System.Data.Common.DataTableMapping _defaultDataTableMapping;
        private System.Data.IDbCommand _defalutConditionSelectCommand;
        /// <summary>
        /// Fill Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>The result of execute command.</returns>
        protected virtual int Fill(object dataObject, object[] primaryKeys, System.Data.IDbTransaction transaction)
        {
            if (CacheDefalutCommand)
            {
                if (_defalutConditionSelectCommand == null)
                {
                    _defalutConditionSelectCommand = this.CommandBuilder.GetConditionSelectCommand(out _defaultDataTableMapping);
                }
                System.Data.Common.DataTableMapping dataTableMapping = _defaultDataTableMapping;
                System.Data.IDbCommand command = _defalutConditionSelectCommand;
                return Fill(command, dataTableMapping, dataObject, primaryKeys, transaction);
            }
            else
            {
                System.Data.Common.DataTableMapping dataTableMapping;
                System.Data.IDbCommand command = this.CommandBuilder.GetConditionSelectCommand(out dataTableMapping);
                return Fill(command, dataTableMapping, dataObject, primaryKeys, transaction);
            }
        }

        /// <summary>
        /// Fill Data object.
        /// </summary>
        /// <param name="dataObject">has primary key value Data object.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>The result of execute command.</returns>
        protected virtual int Fill(object dataObject, System.Data.IDbTransaction transaction)
        {
            return Fill(dataObject, GetPrimaryKeys(dataObject), transaction);
        }

        /// <summary>
        /// Fill Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>The result of execute command.</returns>
        protected virtual int Fill(object dataObject, object[] primaryKeys, string[] columnNames, System.Data.IDbTransaction transaction)
        {
            System.Data.Common.DataTableMapping dataTableMapping;
            System.Data.IDbCommand command = this.CommandBuilder.GetConditionSelectCommand(columnNames, out dataTableMapping);
            return Fill(command, dataTableMapping, dataObject, primaryKeys, columnNames, transaction);
        }

        /// <summary>
        /// Fill Data object.
        /// </summary>
        /// <param name="dataObject">has primary key value Data object.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>The result of execute command.</returns>
        protected virtual int Fill(object dataObject, string[] columnNames, System.Data.IDbTransaction transaction)
        {
            return Fill(dataObject, GetPrimaryKeys(dataObject), columnNames, transaction);
        }

        /// <summary>
        /// Gets Data object.
        /// </summary>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>Data object.</returns>
        protected virtual object GetData(object[] primaryKeys, System.Data.IDbTransaction transaction)
        {
            object dataObject = CreateDataObject();
            Fill(dataObject, primaryKeys, transaction);
            return dataObject;
        }

        /// <summary>
        /// Gets Data object.
        /// </summary>
        /// <param name="dataObject">has primary key value Data object.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>Data object.</returns>
        protected virtual object GetData(object dataObject, System.Data.IDbTransaction transaction)
        {
            Fill(dataObject, transaction);
            return dataObject;
        }

        /// <summary>
        /// Gets Data object.
        /// </summary>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>Data object.</returns>
        protected virtual object GetData(object[] primaryKeys, string[] columnNames, System.Data.IDbTransaction transaction)
        {
            object dataObject = CreateDataObject();
            Fill(dataObject, primaryKeys, columnNames, transaction);
            return dataObject;
        }

        /// <summary>
        /// Gets Data object.
        /// </summary>
        /// <param name="dataObject">has primary key value Data object.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>Data object.</returns>
        protected virtual object GetData(object dataObject, string[] columnNames, System.Data.IDbTransaction transaction)
        {
            Fill(dataObject, columnNames, transaction);
            return dataObject;
        }

        public static bool GetSourceColumnNullMapping(System.Data.IDbDataParameter parameter)
        {
            return DataParameterManager.GetSourceColumnNullMapping(parameter);
        }

        private System.Data.IDbCommand _defalutInsertCommand;
        /// <summary>
        /// Insert Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>The count of rows that updated.</returns>
        protected virtual int Insert(object dataObject, System.Data.IDbTransaction transaction)
        {
            System.Data.IDbCommand command = null;
            if (CacheDefalutCommand)
            {
                if (_defalutInsertCommand == null)
                {
                    _defalutInsertCommand = this.CommandBuilder.GetInsertCommand(this.DefaultDataTableMapping, false);
                }
                command = _defalutInsertCommand;
            }
            else
            {
                command = this.CommandBuilder.GetInsertCommand(this.DefaultDataTableMapping, false);
            }
            SetInsertCommandParameterValues(dataObject, command);
            if (transaction != null)
            {
                command.Transaction = transaction;
            }
            WriteLog(command);
            return RaisingStudio.Data.Common.Database.ExecuteNonQueryCommand(command);
        }

        private void SetInsertCommandParameterValues(object dataObject, System.Data.IDbCommand command)
        {
            if (UseDynamicProxy)
            {
                #region UseDynamicProxy
                System.Type dataObjectType = dataObject.GetType();
                IObjectAccessor objectAccessor = GetObjectAccessor(dataObjectType, this.DefaultDataTableMapping.ColumnMappings);
                SetParameterValues(dataObject, command, dataObjectType, objectAccessor, true);
                #endregion
            }
            else
            {
                if (dataObject is IDataObjectProxy)
                {
                    #region IObjectAccessor
                    IObjectAccessor objectAccessor = dataObject as IObjectAccessor;
                    SetParameterValues(dataObject, command, dataObject as IDataObjectProxy, objectAccessor, true);
                    #endregion
                }
                else
                {
                    #region Reflection
                    System.Type dataObjectType = dataObject.GetType();
                    SetParameterValues(dataObject, command, dataObjectType, true);
                    #endregion
                }
            }
        }


        private void SetParameterValues(object dataObject, System.Data.IDbCommand command, System.Type dataObjectType, IObjectAccessor objectAccessor, bool currentVersion)
        {
            if (objectAccessor != null)
            {
                foreach (System.Data.IDbDataParameter parameter in command.Parameters)
                {
                    if ((!GetSourceColumnNullMapping(parameter)) && (( currentVersion && (parameter.SourceVersion == System.Data.DataRowVersion.Current)) || (!currentVersion)))
                    {
                        string columnName = parameter.SourceColumn;
                        object value = objectAccessor.GetValue(dataObject, columnName);
                        if (value == null)
                        {
                            parameter.Value = System.DBNull.Value;
                        }
                        else
                        {
                            Type propertyType = GetDataObjectPropertyType(dataObjectType, columnName);
                            value = ConvertDataValue(propertyType, parameter.DbType, value);
                            parameter.Value = value;
                        }
                    }
                }
            }
            else
            {
                // TODO: exception.
                throw new ObjectAccessorException(string.Format("Can't get ObjectAccessor for type [{0}].", dataObjectType));
            }
        }

        private void SetParameterValues(object dataObject, System.Data.IDbCommand command, IDataObjectProxy proxy, IObjectAccessor objectAccessor, bool currentVersion)
        {
            if (objectAccessor != null)
            {
                foreach (System.Data.IDbDataParameter parameter in command.Parameters)
                {
                    if ((!GetSourceColumnNullMapping(parameter)) && ((currentVersion && (parameter.SourceVersion == System.Data.DataRowVersion.Current)) || (!currentVersion)))
                    {
                        string columnName = parameter.SourceColumn;
                        object value = objectAccessor.GetValue(dataObject, columnName);
                        if (value == null)
                        {
                            parameter.Value = System.DBNull.Value;
                        }
                        else
                        {
                            Type propertyType = proxy.GetPropertyType(columnName);
                            value = ConvertDataValue(propertyType, parameter.DbType, value);
                            parameter.Value = value;
                        }
                    }
                }
            }
            else
            {
                // TODO: exception.
                throw new ObjectAccessorException(string.Format("Can't get ObjectAccessor for type [{0}].", dataObjectType));
            }
        }

        private void SetParameterValues(object dataObject, System.Data.IDbCommand command, System.Type dataObjectType, bool currentVersion)
        {
            foreach (System.Data.IDbDataParameter parameter in command.Parameters)
            {
                if ((!GetSourceColumnNullMapping(parameter)) && ((currentVersion && (parameter.SourceVersion == System.Data.DataRowVersion.Current)) || (!currentVersion)))
                {
                    string columnName = parameter.SourceColumn;
                    System.Reflection.PropertyInfo propertyInfo = dataObjectType.GetProperty(columnName);
                    if (propertyInfo != null)
                    {
                        object value = propertyInfo.GetValue(dataObject, null);
                        if (value == null)
                        {
                            parameter.Value = System.DBNull.Value;
                        }
                        else
                        {
                            value = ConvertDataValue(propertyInfo.PropertyType, parameter.DbType, value);
                            parameter.Value = value;
                        }
                    }
                    else
                    {
                        throw new System.MissingMemberException(string.Format("Can not find a property named {1} in type  {0}.", dataObjectType, columnName));
                    }
                }
            }
        }


        /// <summary>
        /// Insert Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>The count of rows that updated.</returns>
        protected virtual int Insert(object dataObject, string[] columnNames, System.Data.IDbTransaction transaction)
        {
            System.Data.Common.DataTableMapping dataTableMapping = this.CommandBuilder.CommonCommandBuilder.GetDataTableMapping(columnNames);
            System.Data.IDbCommand command = this.CommandBuilder.GetInsertCommand(dataTableMapping, false);
            SetInsertCommandParameterValues(dataObject, command);
            if (transaction != null)
            {
                command.Transaction = transaction;
            }
            WriteLog(command);
            return RaisingStudio.Data.Common.Database.ExecuteNonQueryCommand(command);
        }

        /// <summary>
        /// Delete Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>The count of rows that updated.</returns>
        protected virtual int Delete(object dataObject, System.Data.IDbTransaction transaction)
        {
            object[] primaryKeys = GetPrimaryKeys(dataObject);
            return Delete(primaryKeys, transaction);
        }

        System.Data.IDbCommand _defaultDeleteCommand;
        /// <summary>
        /// Delete Data object.
        /// </summary>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>The count of rows that updated.</returns>
        protected virtual int Delete(object[] primaryKeys, System.Data.IDbTransaction transaction)
        {
            System.Data.IDbCommand command = null;
            if (CacheDefalutCommand)
            {
                if (_defaultDeleteCommand == null)
                {
                    _defaultDeleteCommand = this.CommandBuilder.GetDeleteCommand(this.DefaultDataTableMapping, false);
                }
                command = _defaultDeleteCommand;
            }
            else
            {
                command = this.CommandBuilder.GetDeleteCommand(this.DefaultDataTableMapping, false);
            }
            int i = 0;
            foreach (System.Data.IDbDataParameter parameter in command.Parameters)
            {
                parameter.Value = primaryKeys[i];
                i++;
            }

            if (transaction != null)
            {
                command.Transaction = transaction;
            }
            WriteLog(command);
            return RaisingStudio.Data.Common.Database.ExecuteNonQueryCommand(command);
        }

        private System.Data.IDbCommand _defalutUpdateCommand;
        /// <summary>
        /// Update Data object.
        /// </summary>
        /// <param name="dataTableMapping">Data table mapping.</param>
        /// <param name="dataObject">Data object.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>The count of rows that updated.</returns>
        protected virtual int Update(System.Data.Common.DataTableMapping dataTableMapping, object dataObject, System.Data.IDbTransaction transaction)
        {
            System.Data.IDbCommand command = this.CommandBuilder.GetUpdateCommand(dataTableMapping, false, false);
            SetUpdateCommandParameterValues(dataObject, command);
            if (transaction != null)
            {
                command.Transaction = transaction;
            }
            WriteLog(command);
            return RaisingStudio.Data.Common.Database.ExecuteNonQueryCommand(command);
        }

        private void SetUpdateCommandParameterValues(object dataObject, System.Data.IDbCommand command)
        {
            if (UseDynamicProxy)
            {
                #region UseDynamicProxy
                System.Type dataObjectType = dataObject.GetType();
                IObjectAccessor objectAccessor = GetObjectAccessor(dataObjectType, this.DefaultDataTableMapping.ColumnMappings);
                SetParameterValues(dataObject, command, dataObjectType, objectAccessor, false);
                #endregion
            }
            else
            {
                if (dataObject is IDataObjectProxy)
                {
                    #region IObjectAccessor
                    IObjectAccessor objectAccessor = dataObject as IObjectAccessor;
                    SetParameterValues(dataObject, command, dataObject as IDataObjectProxy, objectAccessor, false);
                    #endregion
                }
                else
                {
                    #region Reflection
                    System.Type dataObjectType = dataObject.GetType();
                    SetParameterValues(dataObject, command, dataObjectType, false);
                    #endregion
                }
            }
        }

        /// <summary>
        /// Update Data object.
        /// </summary>
        /// <param name="dataTableMapping">Data table mapping.</param>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="dataObject">Data object.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>The count of rows that updated.</returns>
        protected virtual int Update(System.Data.Common.DataTableMapping dataTableMapping, object[] primaryKeys, object dataObject, System.Data.IDbTransaction transaction)
        {
            System.Data.IDbCommand command = this.CommandBuilder.GetUpdateCommand(dataTableMapping, false, false);
            if (UseDynamicProxy)
            {
                #region UseDynamicProxy
                System.Type dataObjectType = dataObject.GetType();
                IObjectAccessor objectAccessor = GetObjectAccessor(dataObjectType, this.DefaultDataTableMapping.ColumnMappings);
                SetParameterValues(primaryKeys, dataObject, command, dataObjectType, objectAccessor);
                #endregion
            }
            else
            {
                if (dataObject is IDataObjectProxy)
                {
                    #region IObjectAccessor
                    IObjectAccessor objectAccessor = dataObject as IObjectAccessor;
                    SetParameterValues(primaryKeys, dataObject, command, dataObject as IDataObjectProxy, objectAccessor);
                    #endregion
                }
                else
                {
                    #region Reflection
                    System.Type dataObjectType = dataObject.GetType();
                    SetParameterValues(primaryKeys, dataObject, command, dataObjectType);
                    #endregion
                }
            }
            if (transaction != null)
            {
                command.Transaction = transaction;
            }
            WriteLog(command);
            return RaisingStudio.Data.Common.Database.ExecuteNonQueryCommand(command);
        }


        private void SetParameterValues(object[] primaryKeys, object dataObject, System.Data.IDbCommand command, System.Type dataObjectType)
        {
            int i = 0;
            foreach (System.Data.IDbDataParameter parameter in command.Parameters)
            {
                if (!GetSourceColumnNullMapping(parameter))
                {
                    if (parameter.SourceVersion == System.Data.DataRowVersion.Original)
                    {
                        parameter.Value = primaryKeys[i];
                        i++;
                    }
                    else
                    {
                        string columnName = parameter.SourceColumn;
                        System.Reflection.PropertyInfo propertyInfo = dataObjectType.GetProperty(columnName);
                        if (propertyInfo != null)
                        {
                            object value = propertyInfo.GetValue(dataObject, null);
                            if (value == null)
                            {
                                parameter.Value = System.DBNull.Value;
                            }
                            else
                            {
                                value = ConvertDataValue(propertyInfo.PropertyType, parameter.DbType, value);
                                parameter.Value = value;
                            }
                        }
                        else
                        {
                            throw new System.MissingMemberException(string.Format("Can not find a property named {1} in type  {0}.", dataObjectType, columnName));
                        }
                    }
                }
            }
        }

        private void SetParameterValues(object[] primaryKeys, object dataObject, System.Data.IDbCommand command, System.Type dataObjectType, IObjectAccessor objectAccessor)
        {
            int i = 0;
            if (objectAccessor != null)
            {
                foreach (System.Data.IDbDataParameter parameter in command.Parameters)
                {
                    if (!GetSourceColumnNullMapping(parameter))
                    {
                        if (parameter.SourceVersion == System.Data.DataRowVersion.Original)
                        {
                            parameter.Value = primaryKeys[i];
                            i++;
                        }
                        else
                        {
                            string columnName = parameter.SourceColumn;
                            object value = objectAccessor.GetValue(dataObject, columnName);
                            if (value == null)
                            {
                                parameter.Value = System.DBNull.Value;
                            }
                            else
                            {
                                Type propertyType = GetDataObjectPropertyType(dataObjectType, columnName);
                                value = ConvertDataValue(propertyType, parameter.DbType, value);
                                parameter.Value = value;
                            }
                        }
                    }
                }
            }
            else
            {
                // TODO: exception.
                throw new ObjectAccessorException(string.Format("Can't get ObjectAccessor for type [{0}].", dataObjectType));
            }
        }

        private void SetParameterValues(object[] primaryKeys, object dataObject, System.Data.IDbCommand command, IDataObjectProxy proxy, IObjectAccessor objectAccessor)
        {
            int i = 0;
            if (objectAccessor != null)
            {
                foreach (System.Data.IDbDataParameter parameter in command.Parameters)
                {
                    if (!GetSourceColumnNullMapping(parameter))
                    {
                        if (parameter.SourceVersion == System.Data.DataRowVersion.Original)
                        {
                            parameter.Value = primaryKeys[i];
                            i++;
                        }
                        else
                        {
                            string columnName = parameter.SourceColumn;
                            object value = objectAccessor.GetValue(dataObject, columnName);
                            if (value == null)
                            {
                                parameter.Value = System.DBNull.Value;
                            }
                            else
                            {
                                Type propertyType = proxy.GetPropertyType(columnName);
                                value = ConvertDataValue(propertyType, parameter.DbType, value);
                                parameter.Value = value;
                            }
                        }
                    }
                }
            }
            else
            {
                // TODO: exception.
                throw new ObjectAccessorException(string.Format("Can't get ObjectAccessor for type [{0}].", dataObjectType));
            }
        }


        /// <summary>
        /// Update Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>The count of rows that updated.</returns>
        protected virtual int Update(object dataObject, System.Data.IDbTransaction transaction)
        {
            System.Data.IDbCommand command = null;
            if (CacheDefalutCommand)
            {
                if (_defalutUpdateCommand == null)
                {
                    _defalutUpdateCommand = this.CommandBuilder.GetUpdateCommand(this.DefaultDataTableMapping, false, false);
                }
                command = _defalutUpdateCommand;
            }
            else
            {
                command = this.CommandBuilder.GetUpdateCommand(this.DefaultDataTableMapping, false, false);
            }
            SetUpdateCommandParameterValues(dataObject, command);
            if (transaction != null)
            {
                command.Transaction = transaction;
            }
            WriteLog(command);
            return RaisingStudio.Data.Common.Database.ExecuteNonQueryCommand(command);
        }

        /// <summary>
        /// Update Data object.
        /// </summary>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="dataObject">Data object.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>The count of rows that updated.</returns>
        protected virtual int Update(object[] primaryKeys, object dataObject, System.Data.IDbTransaction transaction)
        {
            System.Data.IDbCommand command = null;
            if (CacheDefalutCommand)
            {
                if (_defalutUpdateCommand == null)
                {
                    _defalutUpdateCommand = this.CommandBuilder.GetUpdateCommand(this.DefaultDataTableMapping, false, false);
                }
                command = _defalutUpdateCommand;
            }
            else
            {
                command = this.CommandBuilder.GetUpdateCommand(this.DefaultDataTableMapping, false, false);
            }
            if (UseDynamicProxy)
            {
                #region UseDynamicProxy
                System.Type dataObjectType = dataObject.GetType();
                IObjectAccessor objectAccessor = GetObjectAccessor(dataObjectType, this.DefaultDataTableMapping.ColumnMappings);
                SetParameterValues(primaryKeys, dataObject, command, dataObjectType, objectAccessor);
                #endregion
            }
            else
            {
                if (dataObject is IDataObjectProxy)
                {
                    #region IObjectAccessor
                    IObjectAccessor objectAccessor = dataObject as IObjectAccessor;
                    SetParameterValues(primaryKeys, dataObject, command, dataObject as IDataObjectProxy, objectAccessor);
                    #endregion
                }
                else
                {
                    #region Reflection
                    System.Type dataObjectType = dataObject.GetType();
                    SetParameterValues(primaryKeys, dataObject, command, dataObjectType);
                    #endregion
                }
            }
            if (transaction != null)
            {
                command.Transaction = transaction;
            }
            WriteLog(command);
            return RaisingStudio.Data.Common.Database.ExecuteNonQueryCommand(command);
        }

        /// <summary>
        /// Update Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>The count of rows that updated.</returns>
        protected virtual int Update(object dataObject, string[] columnNames, System.Data.IDbTransaction transaction)
        {
            System.Data.Common.DataTableMapping dataTableMapping = this.CommandBuilder.CommonCommandBuilder.GetDataTableMapping(columnNames);
            return Update(dataTableMapping, dataObject, transaction);
        }

        /// <summary>
        /// Update Data object.
        /// </summary>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="dataObject">Data object.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>The count of rows that updated.</returns>
        protected virtual int Update(object[] primaryKeys, object dataObject, string[] columnNames, System.Data.IDbTransaction transaction)
        {
            System.Data.Common.DataTableMapping dataTableMapping = this.CommandBuilder.CommonCommandBuilder.GetDataTableMapping(columnNames);
            return Update(dataTableMapping, primaryKeys, dataObject, transaction);
        }

        /// <summary>
        /// Check data object by primary key.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>If exists then return true, otherwise return false.</returns>
        protected virtual bool Exists(object dataObject, System.Data.IDbTransaction transaction)
        {
            object[] primaryKeys = GetPrimaryKeys(dataObject);
            return Exists(primaryKeys, transaction);
        }

        private System.Data.IDbCommand _defaultExistsCommand;
        /// <summary>
        /// Check data object by primary key.
        /// </summary>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>If exists then return true, otherwise return false.</returns>
        protected virtual bool Exists(object[] primaryKeys, System.Data.IDbTransaction transaction)
        {
            System.Data.IDbCommand command = null;
            if (CacheDefalutCommand)
            {
                if (_defaultExistsCommand == null)
                {
                    _defaultExistsCommand = this.CommandBuilder.GetExistsCommand(this.DefaultDataTableMapping);
                }
                command = _defaultExistsCommand;
            }
            else
            {
                command = this.CommandBuilder.GetExistsCommand(this.DefaultDataTableMapping);
            }
            int i = 0;
            foreach (System.Data.IDbDataParameter parameter in command.Parameters)
            {
                parameter.Value = primaryKeys[i];
                i++;
            }

            if (transaction != null)
            {
                command.Transaction = transaction;
            }
            WriteLog(command);
            int count = Convert.ToInt32(RaisingStudio.Data.Common.Database.ExecuteScalarCommand(command));
            return (count > 0) ? true : false;
        }

        /// <summary>
        /// Save Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>The count of rows that updated.</returns>
        protected virtual int Save(object dataObject, System.Data.IDbTransaction transaction)
        {
            if (Exists(dataObject, transaction))
            {
                return Update(dataObject, transaction);
            }
            else
            {
                return Insert(dataObject, transaction);
            }
        }

        /// <summary>
        /// Save Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>The count of rows that updated.</returns>
        protected virtual int Save(object dataObject, string[] columnNames, System.Data.IDbTransaction transaction)
        {
            if (Exists(dataObject, transaction))
            {
                return Update(dataObject, columnNames, transaction);
            }
            else
            {
                return Insert(dataObject, columnNames, transaction);
            }
        }

        #region Batch Operation
        /// <summary>
        /// Filldata object column table.
        /// </summary>
        /// <param name="command">Command.</param>
        /// <param name="dataObjectList">data object column table.</param>
        /// <param name="columnNames">column name column table.</param>
        /// <param name="propertyInfos">property info dictionary.</param>
        /// <param name="sourceNames">source name dictionary.</param>
        /// <param name="dbTypes">data type dictionary.</param>
        /// <returns>The result of execute command.</returns>
        public int FillDataObjectList(System.Data.IDbCommand command, System.Collections.IList dataObjectList, System.Collections.IList columnNames, Dictionary<string, System.Reflection.PropertyInfo> propertyInfos, Dictionary<string, DataConverter> propertyConverters, Dictionary<string, string> sourceNames, Dictionary<string, System.Data.DbType> dbTypes)
        {
            WriteLog(command);
            System.Data.IDataReader dataReader = RaisingStudio.Data.Common.Database.ExecuteReaderCommand(command);
            int index = 0;
            try
            {
                while (dataReader.Read())
                {
                    object dataObject = CreateDataObject();
                    SetDataObjectValues(columnNames, propertyInfos, propertyConverters, sourceNames, dbTypes, dataReader, dataObject);
                    dataObjectList.Add(dataObject);
                    index++;
                }
            }
            finally
            {
                if (dataReader != null)
                {
                    dataReader.Close();
                }
            }
            return index;
        }

        public void SetDataObjectValues(System.Collections.IList columnNames, Dictionary<string, System.Reflection.PropertyInfo> propertyInfos, Dictionary<string, DataConverter> propertyConverters, Dictionary<string, string> sourceNames, Dictionary<string, System.Data.DbType> dbTypes, System.Data.IDataReader dataReader, object dataObject)
        {
            foreach (string columnName in columnNames)
            {
                object value = DataItemAdapter.GetDataReaderValue(dataReader, sourceNames[columnName], dbTypes[columnName]);
                if (value == System.DBNull.Value)
                {
                    propertyInfos[columnName].SetValue(dataObject, null, null);
                }
                else
                {
                    if (propertyConverters[columnName] != null)
                    {
                        value = propertyConverters[columnName](value);
                    }
                    propertyInfos[columnName].SetValue(dataObject, value, null);
                }
            }
        }

        /// <summary>
        /// Filldata object column table.
        /// </summary>
        /// <param name="command">Command.</param>
        /// <param name="dataTableMapping">Data table mapping.</param>
        /// <param name="dataObjectList">data object column table.</param>
        /// <returns>The result of execute command.</returns>
        public int FillDataObjectList(System.Data.IDbCommand command, System.Data.Common.DataTableMapping dataTableMapping, out System.Collections.IList dataObjectList)
        {
            if (UseDynamicProxy)
            {
                dataObjectList = CreateDataObjectList();
                List<string> columnNames;
                IObjectAccessor objectAccessor;
                Dictionary<string, string> sourceNames;
                Dictionary<string, System.Data.DbType> dbTypes;
                Dictionary<string, DataConverter> propertyConverters;
                BuildMappingInfo(dataTableMapping, out columnNames, out objectAccessor, out propertyConverters, out sourceNames, out dbTypes);

                return FillDataObjectList(command, dataObjectList, columnNames, objectAccessor, propertyConverters, sourceNames, dbTypes);
            }
            else
            {
                if ((typeof(IDataObjectProxy)).IsAssignableFrom(this.dataObjectType))
                {
                    // proxy.
                    IDataObjectProxy proxy = System.Activator.CreateInstance(this.dataObjectType) as IDataObjectProxy;
                    dataObjectList = proxy.CreateObjectList();
                    List<string> columnNames;
                    Dictionary<string, string> sourceNames;
                    Dictionary<string, System.Data.DbType> dbTypes;
                    Dictionary<string, DataConverter> propertyConverters;
                    BuildMappingInfo(dataTableMapping, out columnNames, proxy, out propertyConverters, out sourceNames, out dbTypes);

                    return FillDataObjectList(command, dataObjectList, columnNames, proxy, propertyConverters, sourceNames, dbTypes);
                }
                else
                {
                    dataObjectList = CreateDataObjectList();
                    List<string> columnNames;
                    Dictionary<string, System.Reflection.PropertyInfo> propertyInfos;
                    Dictionary<string, string> sourceNames;
                    Dictionary<string, System.Data.DbType> dbTypes;
                    Dictionary<string, DataConverter> propertyConverters;
                    BuildMappingInfo(dataTableMapping, out columnNames, out propertyInfos, out propertyConverters, out sourceNames, out dbTypes);

                    return FillDataObjectList(command, dataObjectList, columnNames, propertyInfos, propertyConverters, sourceNames, dbTypes);
                }
            }
        }

        /// <summary>
        /// Create mapping infomation.
        /// </summary>
        /// <param name="dataTableMapping">Data table mapping.</param>
        /// <param name="columnNames">column name column table.</param>
        /// <param name="propertyInfos">property info dictionary.</param>
        /// <param name="sourceNames">source name dictionary.</param>
        /// <param name="dbTypes">data type dictionary.</param>
        public void BuildMappingInfo(System.Data.Common.DataTableMapping dataTableMapping, out List<string> columnNames, out Dictionary<string, System.Reflection.PropertyInfo> propertyInfos, out Dictionary<string, DataConverter> propertyConverters, out Dictionary<string, string> sourceNames, out Dictionary<string, System.Data.DbType> dbTypes)
        {
            columnNames = new List<string>();
            propertyInfos = new Dictionary<string, System.Reflection.PropertyInfo>();
            propertyConverters = new Dictionary<string, DataConverter>();
            sourceNames = new Dictionary<string, string>();
            dbTypes = new Dictionary<string, System.Data.DbType>();
            foreach (System.Data.Common.DataColumnMapping dataColumnMapping in dataTableMapping.ColumnMappings)
            {
                string columnName = dataColumnMapping.DataSetColumn;
                System.Reflection.PropertyInfo propertyInfo = this.dataObjectType.GetProperty(columnName);
                if (propertyInfo != null)
                {
                    propertyInfos.Add(columnName, propertyInfo);
                }
                else
                {
                    throw new System.MissingMemberException(string.Format("Can not find a property named {1} in type  {0}.", dataObjectType, columnName));
                }
                columnNames.Add(columnName);

                string sourceName = dataColumnMapping.SourceColumn;
                DataColumnDefinition dataColumnDefinition = this.CommandBuilder.CommonCommandBuilder.DataTableDefinition.Columns[columnName];
                System.Data.DbType dbType = dataColumnDefinition.DbType;

                sourceNames.Add(columnName, sourceName);
                dbTypes.Add(columnName, dbType);

                propertyConverters.Add(columnName, GetDataConverter(dbType, propertyInfo.PropertyType));
            }
        }

        private DataConverter GetDataConverter(System.Data.DbType dbType, Type type)
        {
            return ConverterManager.GetDataConverter(dbType, type);
        }

        /// <summary>
        /// Filldata object column table.
        /// </summary>
        /// <param name="command">Command.</param>
        /// <param name="dataTableMapping">Data table mapping.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="dataItemList">data object column table.</param>
        /// <returns>The result of execute command.</returns>
        public int FillDataObjectList(System.Data.IDbCommand command, System.Data.Common.DataTableMapping dataTableMapping, string[] columnNames, out System.Collections.IList dataObjectList)
        {
            if (UseDynamicProxy)
            {
                dataObjectList = CreateDataObjectList();
                IObjectAccessor objectAccessor;
                Dictionary<string, string> sourceNames;
                Dictionary<string, System.Data.DbType> dbTypes;
                Dictionary<string, DataConverter> propertyConverters;
                BuildMappingInfo(dataTableMapping, columnNames, out objectAccessor, out propertyConverters, out sourceNames, out dbTypes);

                return FillDataObjectList(command, dataObjectList, columnNames, objectAccessor, propertyConverters, sourceNames, dbTypes);
            }
            else
            {
                if ((typeof(IDataObjectProxy)).IsAssignableFrom(this.dataObjectType))
                {
                    // proxy.
                    IDataObjectProxy proxy = System.Activator.CreateInstance(this.dataObjectType) as IDataObjectProxy;
                    dataObjectList = proxy.CreateObjectList();
                    Dictionary<string, string> sourceNames;
                    Dictionary<string, System.Data.DbType> dbTypes;
                    Dictionary<string, DataConverter> propertyConverters;
                    BuildMappingInfo(dataTableMapping, columnNames, proxy, out propertyConverters, out sourceNames, out dbTypes);

                    return FillDataObjectList(command, dataObjectList, columnNames, proxy, propertyConverters, sourceNames, dbTypes);
                }
                else
                {
                    dataObjectList = CreateDataObjectList();
                    Dictionary<string, System.Reflection.PropertyInfo> propertyInfos;
                    Dictionary<string, string> sourceNames;
                    Dictionary<string, System.Data.DbType> dbTypes;
                    Dictionary<string, DataConverter> propertyConverters;
                    BuildMappingInfo(dataTableMapping, columnNames, out propertyInfos, out propertyConverters, out sourceNames, out dbTypes);

                    return FillDataObjectList(command, dataObjectList, columnNames, propertyInfos, propertyConverters, sourceNames, dbTypes);
                }
            }
        }

        /// <summary>
        /// Create mapping infomation.
        /// </summary>
        /// <param name="dataTableMapping">Data table mapping.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="propertyInfos">property info dictionary.</param>
        /// <param name="sourceNames">source name dictionary.</param>
        /// <param name="dbTypes">data type dictionary.</param>
        private void BuildMappingInfo(System.Data.Common.DataTableMapping dataTableMapping, string[] columnNames, out Dictionary<string, System.Reflection.PropertyInfo> propertyInfos, out Dictionary<string, DataConverter> propertyConverters, out Dictionary<string, string> sourceNames, out Dictionary<string, System.Data.DbType> dbTypes)
        {
            propertyInfos = new Dictionary<string, System.Reflection.PropertyInfo>();
            propertyConverters = new Dictionary<string, DataConverter>();
            sourceNames = new Dictionary<string, string>();
            dbTypes = new Dictionary<string, System.Data.DbType>();
            foreach (string columnName in columnNames)
            {
                System.Reflection.PropertyInfo propertyInfo = this.dataObjectType.GetProperty(columnName);
                if (propertyInfo != null)
                {
                    propertyInfos.Add(columnName, propertyInfo);
                }
                else
                {
                    throw new System.MissingMemberException(string.Format("Can not find a property named {1} in type  {0}.", dataObjectType, columnName));
                }
                DataColumnDefinition dataColumnDefinition = this.CommandBuilder.CommonCommandBuilder.DataTableDefinition.Columns[columnName];
                string sourceName = RaisingStudio.Data.Common.Builders.CommonCommandBuilder.GetDataColumnSourceColumn(dataTableMapping, columnName);
                System.Data.DbType dbType = dataColumnDefinition.DbType;
                sourceNames.Add(columnName, sourceName);
                dbTypes.Add(columnName, dbType);

                propertyConverters.Add(columnName, GetDataConverter(dbType, propertyInfo.PropertyType));
            }
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>data object column table.</returns>
        protected virtual System.Collections.IList GetDataList(System.Data.IDbTransaction transaction)
        {
            System.Data.Common.DataTableMapping dataTableMapping;
            System.Data.IDbCommand command = null;
            if (CacheDefalutCommand)
            {
                if (_defalutSelectCommand == null)
                {
                    _defalutSelectCommand = this.CommandBuilder.GetSelectCommand(out _defaultDataTableMapping);
                }
                dataTableMapping = _defaultDataTableMapping;
                command = _defalutSelectCommand;
            }
            else
            {
                command = this.CommandBuilder.GetSelectCommand(out dataTableMapping); ;
            }
            if (transaction != null)
            {
                command.Transaction = transaction;
            }
            System.Collections.IList dataObjectList;
            FillDataObjectList(command, dataTableMapping, out dataObjectList);
            return dataObjectList;
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>data object column table.</returns>
        protected virtual System.Collections.IList GetDataList(string[] columnNames, System.Data.IDbTransaction transaction)
        {
            System.Data.Common.DataTableMapping dataTableMapping;
            System.Data.IDbCommand command = this.CommandBuilder.GetSelectCommand(columnNames, out dataTableMapping);
            if (transaction != null)
            {
                command.Transaction = transaction;
            }
            System.Collections.IList dataObjectList;
            FillDataObjectList(command, dataTableMapping, columnNames, out dataObjectList);
            return dataObjectList;
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>data object column table.</returns>
        protected virtual System.Collections.IList GetDataList(CommonCommand conditionCommand, System.Data.IDbTransaction transaction)
        {
            System.Data.Common.DataTableMapping dataTableMapping;
            System.Data.IDbCommand command = this.CommandBuilder.GetSelectCommand(conditionCommand, out dataTableMapping);
            if (transaction != null)
            {
                command.Transaction = transaction;
            }
            System.Collections.IList dataObjectList;
            FillDataObjectList(command, dataTableMapping, out dataObjectList);
            return dataObjectList;
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>data object column table.</returns>
        protected virtual System.Collections.IList GetDataList(string[] columnNames, CommonCommand conditionCommand, System.Data.IDbTransaction transaction)
        {
            System.Data.Common.DataTableMapping dataTableMapping;
            System.Data.IDbCommand command = this.CommandBuilder.GetSelectCommand(columnNames, conditionCommand, out dataTableMapping);
            if (transaction != null)
            {
                command.Transaction = transaction;
            }
            System.Collections.IList dataObjectList;
            FillDataObjectList(command, dataTableMapping, columnNames, out dataObjectList);
            return dataObjectList;
        }

        #region Paging Operation 
        /// <summary>
        /// Filldata object column table.
        /// </summary>
        /// <param name="command">Command.</param>
        /// <param name="dataObjectList">data object column table.</param>
        /// <param name="columnNames">column name column table.</param>
        /// <param name="propertyInfos">property info dictionary.</param>
        /// <param name="sourceNames">source name dictionary.</param>
        /// <param name="dbTypes">data type dictionary.</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <returns>The result of execute command.</returns>
        private int FillDataObjectList(System.Data.IDbCommand command, System.Collections.IList dataObjectList, System.Collections.IList columnNames, Dictionary<string, System.Reflection.PropertyInfo> propertyInfos, Dictionary<string, DataConverter> propertyConverters, Dictionary<string, string> sourceNames, Dictionary<string, System.Data.DbType> dbTypes, int startRecord, int maxRecords)
        {
            WriteLog(command);
            System.Data.IDataReader dataReader = RaisingStudio.Data.Common.Database.ExecuteReaderCommand(command);
            int index = 0;
            int count = 0;
            try
            {
                while ((dataReader.Read()) && (count < maxRecords))
                {
                    if (index >= startRecord)
                    {
                        object dataObject = CreateDataObject();
                        foreach (string columnName in columnNames)
                        {
                            object value = DataItemAdapter.GetDataReaderValue(dataReader, sourceNames[columnName], dbTypes[columnName]);
                            if (value == System.DBNull.Value)
                            {
                                propertyInfos[columnName].SetValue(dataObject, null, null);
                            }
                            else
                            {
                                if (propertyConverters[columnName] != null)
                                {
                                    value = propertyConverters[columnName](value);
                                }
                                propertyInfos[columnName].SetValue(dataObject, value, null);
                            }
                        }
                        dataObjectList.Add(dataObject);
                        count++;
                    }
                    index++;
                }
            }
            finally
            {
                if (dataReader != null)
                {
                    dataReader.Close();
                }
            }
            return count;
        }

        /// <summary>
        /// Filldata object column table.
        /// </summary>
        /// <param name="command">Command.</param>
        /// <param name="dataTableMapping">Data table mapping.</param>
        /// <param name="dataObjectList">data object column table.</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <returns>The result of execute command.</returns>
        protected int FillDataObjectList(System.Data.IDbCommand command, System.Data.Common.DataTableMapping dataTableMapping, out System.Collections.IList dataObjectList, int startRecord, int maxRecords)
        {
            if (UseDynamicProxy)
            {
                dataObjectList = CreateDataObjectList();
                List<string> columnNames;
                IObjectAccessor objectAccessor;
                Dictionary<string, string> sourceNames;
                Dictionary<string, System.Data.DbType> dbTypes;
                Dictionary<string, DataConverter> propertyConverters;
                BuildMappingInfo(dataTableMapping, out columnNames, out objectAccessor, out propertyConverters, out sourceNames, out dbTypes);

                return FillDataObjectList(command, dataObjectList, columnNames, objectAccessor, propertyConverters, sourceNames, dbTypes, startRecord, maxRecords);
            }
            else
            {
                if ((typeof(IDataObjectProxy)).IsAssignableFrom(this.dataObjectType))
                {
                    // proxy.
                    IDataObjectProxy proxy = System.Activator.CreateInstance(this.dataObjectType) as IDataObjectProxy;
                    dataObjectList = proxy.CreateObjectList();
                    List<string> columnNames;
                    Dictionary<string, string> sourceNames;
                    Dictionary<string, System.Data.DbType> dbTypes;
                    Dictionary<string, DataConverter> propertyConverters;
                    BuildMappingInfo(dataTableMapping, out columnNames, proxy, out propertyConverters, out sourceNames, out dbTypes);

                    return FillDataObjectList(command, dataObjectList, columnNames, proxy, propertyConverters, sourceNames, dbTypes, startRecord, maxRecords);
                }
                else
                {
                    dataObjectList = CreateDataObjectList();
                    List<string> columnNames;
                    Dictionary<string, System.Reflection.PropertyInfo> propertyInfos;
                    Dictionary<string, string> sourceNames;
                    Dictionary<string, System.Data.DbType> dbTypes;
                    Dictionary<string, DataConverter> propertyConverters;
                    BuildMappingInfo(dataTableMapping, out columnNames, out propertyInfos, out propertyConverters, out sourceNames, out dbTypes);

                    return FillDataObjectList(command, dataObjectList, columnNames, propertyInfos, propertyConverters, sourceNames, dbTypes, startRecord, maxRecords);
                }
            }
        }

        /// <summary>
        /// Filldata object column table.
        /// </summary>
        /// <param name="command">Command.</param>
        /// <param name="dataTableMapping">Data table mapping.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="dataItemList">data object column table.</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <returns>The result of execute command.</returns>
        protected int FillDataObjectList(System.Data.IDbCommand command, System.Data.Common.DataTableMapping dataTableMapping, string[] columnNames, out System.Collections.IList dataObjectList, int startRecord, int maxRecords)
        {
            if (UseDynamicProxy)
            {
                dataObjectList = CreateDataObjectList();
                IObjectAccessor objectAccessor;
                Dictionary<string, string> sourceNames;
                Dictionary<string, System.Data.DbType> dbTypes;
                Dictionary<string, DataConverter> propertyConverters;
                BuildMappingInfo(dataTableMapping, columnNames, out objectAccessor, out propertyConverters, out sourceNames, out dbTypes);

                return FillDataObjectList(command, dataObjectList, columnNames, objectAccessor, propertyConverters, sourceNames, dbTypes, startRecord, maxRecords);
            }
            else
            {
                if ((typeof(IDataObjectProxy)).IsAssignableFrom(this.dataObjectType))
                {
                    // proxy.
                    IDataObjectProxy proxy = System.Activator.CreateInstance(this.dataObjectType) as IDataObjectProxy;
                    dataObjectList = proxy.CreateObjectList();
                    Dictionary<string, string> sourceNames;
                    Dictionary<string, System.Data.DbType> dbTypes;
                    Dictionary<string, DataConverter> propertyConverters;
                    BuildMappingInfo(dataTableMapping, columnNames, proxy, out propertyConverters, out sourceNames, out dbTypes);

                    return FillDataObjectList(command, dataObjectList, columnNames, proxy, propertyConverters, sourceNames, dbTypes, startRecord, maxRecords);
                }
                else
                {
                    dataObjectList = CreateDataObjectList();
                    Dictionary<string, System.Reflection.PropertyInfo> propertyInfos;
                    Dictionary<string, string> sourceNames;
                    Dictionary<string, System.Data.DbType> dbTypes;
                    Dictionary<string, DataConverter> propertyConverters;
                    BuildMappingInfo(dataTableMapping, columnNames, out propertyInfos, out propertyConverters, out sourceNames, out dbTypes);

                    return FillDataObjectList(command, dataObjectList, columnNames, propertyInfos, propertyConverters, sourceNames, dbTypes, startRecord, maxRecords);
                }
            }
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>data object column table.</returns>
        protected virtual System.Collections.IList GetDataList(int startRecord, int maxRecords, System.Data.IDbTransaction transaction)
        {
            System.Data.Common.DataTableMapping dataTableMapping;
            System.Data.IDbCommand command = this.CommandBuilder.GetSelectCommand(out dataTableMapping);
            if (transaction != null)
            {
                command.Transaction = transaction;
            }
            System.Collections.IList dataObjectList;
            FillDataObjectList(command, dataTableMapping, out dataObjectList, startRecord, maxRecords);
            return dataObjectList;
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>data object column table.</returns>
        protected virtual System.Collections.IList GetDataList(string[] columnNames, int startRecord, int maxRecords, System.Data.IDbTransaction transaction)
        {
            System.Data.Common.DataTableMapping dataTableMapping;
            System.Data.IDbCommand command = this.CommandBuilder.GetSelectCommand(columnNames, out dataTableMapping);
            if (transaction != null)
            {
                command.Transaction = transaction;
            }
            System.Collections.IList dataObjectList;
            FillDataObjectList(command, dataTableMapping, columnNames, out dataObjectList, startRecord, maxRecords);
            return dataObjectList;
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>data object column table.</returns>
        protected virtual System.Collections.IList GetDataList(CommonCommand conditionCommand, int startRecord, int maxRecords, System.Data.IDbTransaction transaction)
        {
            System.Data.Common.DataTableMapping dataTableMapping;
            System.Data.IDbCommand command = this.CommandBuilder.GetSelectCommand(conditionCommand, out dataTableMapping);
            if (transaction != null)
            {
                command.Transaction = transaction;
            }
            System.Collections.IList dataObjectList;
            FillDataObjectList(command, dataTableMapping, out dataObjectList, startRecord, maxRecords);
            return dataObjectList;
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>data object column table.</returns>
        protected virtual System.Collections.IList GetDataList(string[] columnNames, CommonCommand conditionCommand, int startRecord, int maxRecords, System.Data.IDbTransaction transaction)
        {
            System.Data.Common.DataTableMapping dataTableMapping;
            System.Data.IDbCommand command = this.CommandBuilder.GetSelectCommand(columnNames, conditionCommand, out dataTableMapping);
            if (transaction != null)
            {
                command.Transaction = transaction;
            }
            System.Collections.IList dataObjectList;
            FillDataObjectList(command, dataTableMapping, columnNames, out dataObjectList, startRecord, maxRecords);
            return dataObjectList;
        }
        #endregion

        #region Enumerator
        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="command">Command.</param>
        /// <param name="columnNames">column name column table.</param>
        /// <param name="propertyInfos">property info dictionary.</param>
        /// <param name="sourceNames">source name dictionary.</param>
        /// <param name="dbTypes">data type dictionary.</param>
        /// <returns>the enumerator of data objects.</returns>
        private System.Collections.IEnumerable GetEnumerator(System.Data.IDbCommand command, System.Collections.IList columnNames, Dictionary<string, System.Reflection.PropertyInfo> propertyInfos, Dictionary<string, DataConverter> propertyConverters, Dictionary<string, string> sourceNames, Dictionary<string, System.Data.DbType> dbTypes)
        {
            WriteLog(command);
            System.Data.IDataReader dataReader = RaisingStudio.Data.Common.Database.ExecuteReaderCommand(command);
            try
            {
                while (dataReader.Read())
                {
                    object dataObject = CreateDataObject();
                    foreach (string columnName in columnNames)
                    {
                        object value = DataItemAdapter.GetDataReaderValue(dataReader, sourceNames[columnName], dbTypes[columnName]);
                        if (value == System.DBNull.Value)
                        {
                            propertyInfos[columnName].SetValue(dataObject, null, null);
                        }
                        else
                        {
                            if (propertyConverters[columnName] != null)
                            {
                                value = propertyConverters[columnName](value);
                            }
                            propertyInfos[columnName].SetValue(dataObject, value, null);
                        }
                    }
                    yield return dataObject;
                }
            }
            finally
            {
                if (dataReader != null)
                {
                    dataReader.Close();
                }
            }
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="command">Command.</param>
        /// <param name="dataTableMapping">Data table mapping.</param>
        /// <returns>the enumerator of data objects.</returns>
        protected System.Collections.IEnumerable GetEnumerator(System.Data.IDbCommand command, System.Data.Common.DataTableMapping dataTableMapping)
        {
            if (UseDynamicProxy)
            {
                List<string> columnNames;
                IObjectAccessor objectAccessor;
                Dictionary<string, string> sourceNames;
                Dictionary<string, System.Data.DbType> dbTypes;
                Dictionary<string, DataConverter> propertyConverters;
                BuildMappingInfo(dataTableMapping, out columnNames, out objectAccessor, out propertyConverters, out sourceNames, out dbTypes);

                return GetEnumerator(command, columnNames, objectAccessor, propertyConverters, sourceNames, dbTypes);
            }
            else
            {
                if ((typeof(IDataObjectProxy)).IsAssignableFrom(this.dataObjectType))
                {
                    // proxy.
                    IDataObjectProxy proxy = System.Activator.CreateInstance(this.dataObjectType) as IDataObjectProxy;
                    List<string> columnNames;
                    Dictionary<string, string> sourceNames;
                    Dictionary<string, System.Data.DbType> dbTypes;
                    Dictionary<string, DataConverter> propertyConverters;
                    BuildMappingInfo(dataTableMapping, out columnNames, proxy, out propertyConverters, out sourceNames, out dbTypes);

                    return GetEnumerator(command, columnNames, proxy, propertyConverters, sourceNames, dbTypes);
                }
                else
                {
                    List<string> columnNames;
                    Dictionary<string, System.Reflection.PropertyInfo> propertyInfos;
                    Dictionary<string, string> sourceNames;
                    Dictionary<string, System.Data.DbType> dbTypes;
                    Dictionary<string, DataConverter> propertyConverters;
                    BuildMappingInfo(dataTableMapping, out columnNames, out propertyInfos, out propertyConverters, out sourceNames, out dbTypes);

                    return GetEnumerator(command, columnNames, propertyInfos, propertyConverters, sourceNames, dbTypes);
                }
            }
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="command">Command.</param>
        /// <param name="dataTableMapping">Data table mapping.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <returns>The result of execute command.</returns>
        protected System.Collections.IEnumerable GetEnumerator(System.Data.IDbCommand command, System.Data.Common.DataTableMapping dataTableMapping, string[] columnNames)
        {
            if (UseDynamicProxy)
            {
                IObjectAccessor objectAccessor;
                Dictionary<string, string> sourceNames;
                Dictionary<string, System.Data.DbType> dbTypes;
                Dictionary<string, DataConverter> propertyConverters;
                BuildMappingInfo(dataTableMapping, columnNames, out objectAccessor, out propertyConverters, out sourceNames, out dbTypes);

                return GetEnumerator(command, columnNames, objectAccessor, propertyConverters, sourceNames, dbTypes);
            }
            else
            {
                if ((typeof(IDataObjectProxy)).IsAssignableFrom(this.dataObjectType))
                {
                    // proxy.
                    IDataObjectProxy proxy = System.Activator.CreateInstance(this.dataObjectType) as IDataObjectProxy;
                    Dictionary<string, string> sourceNames;
                    Dictionary<string, System.Data.DbType> dbTypes;
                    Dictionary<string, DataConverter> propertyConverters;
                    BuildMappingInfo(dataTableMapping, columnNames, proxy, out propertyConverters, out sourceNames, out dbTypes);

                    return GetEnumerator(command, columnNames, proxy, propertyConverters, sourceNames, dbTypes);
                }
                else
                {
                    Dictionary<string, System.Reflection.PropertyInfo> propertyInfos;
                    Dictionary<string, string> sourceNames;
                    Dictionary<string, System.Data.DbType> dbTypes;
                    Dictionary<string, DataConverter> propertyConverters;
                    BuildMappingInfo(dataTableMapping, columnNames, out propertyInfos, out propertyConverters, out sourceNames, out dbTypes);

                    return GetEnumerator(command, columnNames, propertyInfos, propertyConverters, sourceNames, dbTypes);
                }
            }
        }

        private System.Data.IDbCommand _defalutSelectCommand;
        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>the enumerator of data objects.</returns>
        protected virtual System.Collections.IEnumerable GetEnumerator(System.Data.IDbTransaction transaction)
        {
            System.Data.Common.DataTableMapping dataTableMapping;
            System.Data.IDbCommand command = null;
            if (CacheDefalutCommand)
            {
                if (_defalutSelectCommand == null)
                {
                    _defalutSelectCommand = this.CommandBuilder.GetSelectCommand(out _defaultDataTableMapping);
                }
                dataTableMapping = _defaultDataTableMapping;
                command = _defalutSelectCommand;
            }
            else
            {
                command = this.CommandBuilder.GetSelectCommand(out dataTableMapping); ;
            }
            if (transaction != null)
            {
                command.Transaction = transaction;
            }

            return GetEnumerator(command, dataTableMapping);
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>the enumerator of data objects.</returns>
        protected virtual System.Collections.IEnumerable GetEnumerator(string[] columnNames, System.Data.IDbTransaction transaction)
        {
            System.Data.Common.DataTableMapping dataTableMapping;
            System.Data.IDbCommand command = this.CommandBuilder.GetSelectCommand(columnNames, out dataTableMapping);
            if (transaction != null)
            {
                command.Transaction = transaction;
            }

            return GetEnumerator(command, dataTableMapping, columnNames);
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>the enumerator of data objects.</returns>
        protected virtual System.Collections.IEnumerable GetEnumerator(CommonCommand conditionCommand, System.Data.IDbTransaction transaction)
        {
            System.Data.Common.DataTableMapping dataTableMapping;
            System.Data.IDbCommand command = this.CommandBuilder.GetSelectCommand(conditionCommand, out dataTableMapping);
            if (transaction != null)
            {
                command.Transaction = transaction;
            }

            return GetEnumerator(command, dataTableMapping);
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>the enumerator of data objects.</returns>
        protected virtual System.Collections.IEnumerable GetEnumerator(string[] columnNames, CommonCommand conditionCommand, System.Data.IDbTransaction transaction)
        {
            System.Data.Common.DataTableMapping dataTableMapping;
            System.Data.IDbCommand command = this.CommandBuilder.GetSelectCommand(columnNames, conditionCommand, out dataTableMapping);
            if (transaction != null)
            {
                command.Transaction = transaction;
            }

            return GetEnumerator(command, dataTableMapping, columnNames);
        }

        #region Paging Operation 
        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="command">Command.</param>
        /// <param name="columnNames">column name column table.</param>
        /// <param name="propertyInfos">property info dictionary.</param>
        /// <param name="sourceNames">source name dictionary.</param>
        /// <param name="dbTypes">data type dictionary.</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <returns>the enumerator of data objects.</returns>
        private System.Collections.IEnumerable GetEnumerator(System.Data.IDbCommand command, System.Collections.IList columnNames, Dictionary<string, System.Reflection.PropertyInfo> propertyInfos, Dictionary<string, DataConverter> propertyConverters, Dictionary<string, string> sourceNames, Dictionary<string, System.Data.DbType> dbTypes, int startRecord, int maxRecords)
        {
            WriteLog(command);
            System.Data.IDataReader dataReader = RaisingStudio.Data.Common.Database.ExecuteReaderCommand(command);
            int index = 0;
            int count = 0;
            try
            {
                while ((dataReader.Read()) && (count < maxRecords))
                {
                    if (index >= startRecord)
                    {
                        object dataObject = CreateDataObject();
                        foreach (string columnName in columnNames)
                        {
                            object value = DataItemAdapter.GetDataReaderValue(dataReader, sourceNames[columnName], dbTypes[columnName]);
                            if (value == System.DBNull.Value)
                            {
                                propertyInfos[columnName].SetValue(dataObject, null, null);
                            }
                            else
                            {
                                if (propertyConverters[columnName] != null)
                                {
                                    value = propertyConverters[columnName](value);
                                }
                                propertyInfos[columnName].SetValue(dataObject, value, null);
                            }
                        }
                        yield return dataObject;
                        count++;
                    }
                    index++;
                }
            }
            finally
            {
                if (dataReader != null)
                {
                    dataReader.Close();
                }
            }
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="command">Command.</param>
        /// <param name="dataTableMapping">Data table mapping.</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <returns>the enumerator of data objects.</returns>
        protected System.Collections.IEnumerable GetEnumerator(System.Data.IDbCommand command, System.Data.Common.DataTableMapping dataTableMapping, int startRecord, int maxRecords)
        {
            if (UseDynamicProxy)
            {
                List<string> columnNames;
                IObjectAccessor objectAccessor;
                Dictionary<string, string> sourceNames;
                Dictionary<string, System.Data.DbType> dbTypes;
                Dictionary<string, DataConverter> propertyConverters;
                BuildMappingInfo(dataTableMapping, out columnNames, out objectAccessor, out propertyConverters, out sourceNames, out dbTypes);

                return GetEnumerator(command, columnNames, objectAccessor, propertyConverters, sourceNames, dbTypes, startRecord, maxRecords);
            }
            else
            {
                if ((typeof(IDataObjectProxy)).IsAssignableFrom(this.dataObjectType))
                {
                    // proxy.
                    IDataObjectProxy proxy = System.Activator.CreateInstance(this.dataObjectType) as IDataObjectProxy;
                    List<string> columnNames;
                    Dictionary<string, string> sourceNames;
                    Dictionary<string, System.Data.DbType> dbTypes;
                    Dictionary<string, DataConverter> propertyConverters;
                    BuildMappingInfo(dataTableMapping, out columnNames, proxy, out propertyConverters, out sourceNames, out dbTypes);

                    return GetEnumerator(command, columnNames, proxy, propertyConverters, sourceNames, dbTypes, startRecord, maxRecords);
                }
                else
                {
                    List<string> columnNames;
                    Dictionary<string, System.Reflection.PropertyInfo> propertyInfos;
                    Dictionary<string, string> sourceNames;
                    Dictionary<string, System.Data.DbType> dbTypes;
                    Dictionary<string, DataConverter> propertyConverters;
                    BuildMappingInfo(dataTableMapping, out columnNames, out propertyInfos, out propertyConverters, out sourceNames, out dbTypes);

                    return GetEnumerator(command, columnNames, propertyInfos, propertyConverters, sourceNames, dbTypes, startRecord, maxRecords);
                }
            }
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="command">Command.</param>
        /// <param name="dataTableMapping">Data table mapping.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <returns>the enumerator of data objects.</returns>
        protected System.Collections.IEnumerable GetEnumerator(System.Data.IDbCommand command, System.Data.Common.DataTableMapping dataTableMapping, string[] columnNames, int startRecord, int maxRecords)
        {
            if (UseDynamicProxy)
            {
                IObjectAccessor objectAccessor;
                Dictionary<string, string> sourceNames;
                Dictionary<string, System.Data.DbType> dbTypes;
                Dictionary<string, DataConverter> propertyConverters;
                BuildMappingInfo(dataTableMapping, columnNames, out objectAccessor, out propertyConverters, out sourceNames, out dbTypes);

                return GetEnumerator(command, columnNames, objectAccessor, propertyConverters, sourceNames, dbTypes, startRecord, maxRecords);
            }
            else
            {
                if ((typeof(IDataObjectProxy)).IsAssignableFrom(this.dataObjectType))
                {
                    // proxy.
                    IDataObjectProxy proxy = System.Activator.CreateInstance(this.dataObjectType) as IDataObjectProxy;
                    Dictionary<string, string> sourceNames;
                    Dictionary<string, System.Data.DbType> dbTypes;
                    Dictionary<string, DataConverter> propertyConverters;
                    BuildMappingInfo(dataTableMapping, columnNames, proxy, out propertyConverters, out sourceNames, out dbTypes);

                    return GetEnumerator(command, columnNames, proxy, propertyConverters, sourceNames, dbTypes, startRecord, maxRecords);
                }
                else
                {
                    Dictionary<string, System.Reflection.PropertyInfo> propertyInfos;
                    Dictionary<string, string> sourceNames;
                    Dictionary<string, System.Data.DbType> dbTypes;
                    Dictionary<string, DataConverter> propertyConverters;
                    BuildMappingInfo(dataTableMapping, columnNames, out propertyInfos, out propertyConverters, out sourceNames, out dbTypes);

                    return GetEnumerator(command, columnNames, propertyInfos, propertyConverters, sourceNames, dbTypes, startRecord, maxRecords);
                }
            }
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>the enumerator of data objects.</returns>
        protected virtual System.Collections.IEnumerable GetEnumerator(int startRecord, int maxRecords, System.Data.IDbTransaction transaction)
        {
            System.Data.Common.DataTableMapping dataTableMapping;
            System.Data.IDbCommand command = this.CommandBuilder.GetSelectCommand(out dataTableMapping);
            if (transaction != null)
            {
                command.Transaction = transaction;
            }

            return GetEnumerator(command, dataTableMapping, startRecord, maxRecords);
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>the enumerator of data objects.</returns>
        protected virtual System.Collections.IEnumerable GetEnumerator(string[] columnNames, int startRecord, int maxRecords, System.Data.IDbTransaction transaction)
        {
            System.Data.Common.DataTableMapping dataTableMapping;
            System.Data.IDbCommand command = this.CommandBuilder.GetSelectCommand(columnNames, out dataTableMapping);
            if (transaction != null)
            {
                command.Transaction = transaction;
            }

            return GetEnumerator(command, dataTableMapping, columnNames, startRecord, maxRecords);
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>the enumerator of data objects.</returns>
        protected virtual System.Collections.IEnumerable GetEnumerator(CommonCommand conditionCommand, int startRecord, int maxRecords, System.Data.IDbTransaction transaction)
        {
            System.Data.Common.DataTableMapping dataTableMapping;
            System.Data.IDbCommand command = this.CommandBuilder.GetSelectCommand(conditionCommand, out dataTableMapping);
            if (transaction != null)
            {
                command.Transaction = transaction;
            }

            return GetEnumerator(command, dataTableMapping, startRecord, maxRecords);
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>the enumerator of data objects.</returns>
        protected virtual System.Collections.IEnumerable GetEnumerator(string[] columnNames, CommonCommand conditionCommand, int startRecord, int maxRecords, System.Data.IDbTransaction transaction)
        {
            System.Data.Common.DataTableMapping dataTableMapping;
            System.Data.IDbCommand command = this.CommandBuilder.GetSelectCommand(columnNames, conditionCommand, out dataTableMapping);
            if (transaction != null)
            {
                command.Transaction = transaction;
            }

            return GetEnumerator(command, dataTableMapping, columnNames, startRecord, maxRecords);
        }
        #endregion
        #endregion
        #endregion

        #region Relation Operation
        /// <summary>
        /// Fill Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>The result of execute command.</returns>
        protected virtual int FillByRelation(object dataObject, object[] primaryKeys, System.Data.IDbTransaction transaction)
        {
            throw new System.NotImplementedException("此方法Function 尚未实现，敬请关注！");
        }

        /// <summary>
        /// Fill Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="columnNamesDictionary">column name array dictionary.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>The result of execute command.</returns>
        protected virtual int FillByRelation(object dataObject, object[] primaryKeys, Dictionary<string, string[]> columnNamesDictionary, System.Data.IDbTransaction transaction)
        {
            throw new System.NotImplementedException("此方法Function 尚未实现，敬请关注！");
        }

        /// <summary>
        /// Gets Data object.
        /// </summary>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>Data object.</returns>
        protected virtual object GetDataByRelation(object[] primaryKeys, System.Data.IDbTransaction transaction)
        {
            throw new System.NotImplementedException("此方法Function 尚未实现，敬请关注！");
        }

        /// <summary>
        /// Gets Data object.
        /// </summary>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="columnNamesDictionary">column name array dictionary.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>Data object.</returns>
        protected virtual object GetDataByRelation(object[] primaryKeys, Dictionary<string, string[]> columnNamesDictionary, System.Data.IDbTransaction transaction)
        {
            throw new System.NotImplementedException("此方法Function 尚未实现，敬请关注！");
        }

        /// <summary>
        /// Delete the data according the condition.
        /// </summary>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>The count of rows that updated.</returns>
        protected virtual int DeleteByRelation(object[] primaryKeys, System.Data.IDbTransaction transaction)
        {
            throw new System.NotImplementedException("此方法Function 尚未实现，敬请关注！");
        }
        #endregion
        #endregion

        #region Common Methods
        /// <summary>
        /// Fill Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <returns>The result of execute command.</returns>
        public virtual int Fill(object dataObject, object[] primaryKeys)
        {
            return this.Fill(dataObject, primaryKeys, this.TransactionManager.DefaultTransaction);
        }

        /// <summary>
        /// Fill Data object.
        /// </summary>
        /// <param name="dataObject">has primary key value Data object.</param>
        /// <returns>The result of execute command.</returns>
        public virtual int Fill(object dataObject)
        {
            return this.Fill(dataObject, this.TransactionManager.DefaultTransaction);
        }

        /// <summary>
        /// Fill Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <returns>The result of execute command.</returns>
        public virtual int Fill(object dataObject, object[] primaryKeys, string[] columnNames)
        {
            return this.Fill(dataObject, primaryKeys, columnNames, this.TransactionManager.DefaultTransaction);
        }

        /// <summary>
        /// Fill Data object.
        /// </summary>
        /// <param name="dataObject">has primary key value Data object.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <returns>The result of execute command.</returns>
        public virtual int Fill(object dataObject, string[] columnNames)
        {
            return this.Fill(dataObject, columnNames, this.TransactionManager.DefaultTransaction);
        }

        /// <summary>
        /// Gets Data object.
        /// </summary>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <returns>Data object.</returns>
        public virtual object GetData(object[] primaryKeys)
        {
            return this.GetData(primaryKeys, this.TransactionManager.DefaultTransaction);
        }

        /// <summary>
        /// Gets Data object.
        /// </summary>
        /// <param name="dataObject">has primary key value Data object.</param>
        /// <returns>Data object.</returns>
        public virtual object GetData(object dataObject)
        {
            return this.GetData(dataObject, this.TransactionManager.DefaultTransaction);
        }

        /// <summary>
        /// Gets Data object.
        /// </summary>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <returns>Data object.</returns>
        public virtual object GetData(object[] primaryKeys, string[] columnNames)
        {
            return this.GetData(primaryKeys, columnNames, this.TransactionManager.DefaultTransaction);
        }

        /// <summary>
        /// Gets Data object.
        /// </summary>
        /// <param name="dataObject">has primary key value Data object.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <returns>Data object.</returns>
        public virtual object GetData(object dataObject, string[] columnNames)
        {
            return this.GetData(dataObject, columnNames, this.TransactionManager.DefaultTransaction);
        }

        /// <summary>
        /// Insert Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int Insert(object dataObject)
        {
            return this.Insert(dataObject, this.TransactionManager.DefaultTransaction);
        }

        /// <summary>
        /// Insert Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int Insert(object dataObject, string[] columnNames)
        {
            return this.Insert(dataObject, columnNames, this.TransactionManager.DefaultTransaction);
        }

        /// <summary>
        /// Delete Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int Delete(object dataObject)
        {
            return this.Delete(dataObject, this.TransactionManager.DefaultTransaction);
        }

        /// <summary>
        /// Delete Data object.
        /// </summary>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int Delete(object[] primaryKeys)
        {
            return this.Delete(primaryKeys, this.TransactionManager.DefaultTransaction);
        }

        /// <summary>
        /// Update Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int Update(object dataObject)
        {
            return this.Update(dataObject, this.TransactionManager.DefaultTransaction);
        }

        /// <summary>
        /// Update Data object.
        /// </summary>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="dataObject">Data object.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int Update(object[] primaryKeys, object dataObject)
        {
            return this.Update(primaryKeys, dataObject, this.TransactionManager.DefaultTransaction);
        }

        /// <summary>
        /// Update Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int Update(object dataObject, string[] columnNames)
        {
            return this.Update(dataObject, columnNames, this.TransactionManager.DefaultTransaction);
        }

        /// <summary>
        /// Update Data object.
        /// </summary>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="dataObject">Data object.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int Update(object[] primaryKeys, object dataObject, string[] columnNames)
        {
            return this.Update(primaryKeys, dataObject, columnNames, this.TransactionManager.DefaultTransaction);
        }

        /// <summary>
        /// Check data object by primary key.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <returns>If exists then return true, otherwise return false.</returns>
        public virtual bool Exists(object dataObject)
        {
            return this.Exists(dataObject, this.TransactionManager.DefaultTransaction);
        }

        /// <summary>
        /// Check data object by primary key.
        /// </summary>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <returns>If exists then return true, otherwise return false.</returns>
        public virtual bool Exists(object[] primaryKeys)
        {
            return this.Exists(primaryKeys, this.TransactionManager.DefaultTransaction);
        }

        /// <summary>
        /// Save Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int Save(object dataObject)
        {
            return this.Save(dataObject, this.TransactionManager.DefaultTransaction);
        }

        /// <summary>
        /// Save Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int Save(object dataObject, string[] columnNames)
        {
            return this.Save(dataObject, columnNames, this.TransactionManager.DefaultTransaction);
        }

        #region Batch Operation
        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <returns>data object column table.</returns>
        public virtual System.Collections.IList GetDataList()
        {
            return GetDataList(this.TransactionManager.DefaultTransaction);
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <returns>data object column table.</returns>
        public virtual System.Collections.IList GetDataList(string[] columnNames)
        {
            return GetDataList(columnNames, this.TransactionManager.DefaultTransaction);
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <returns>data object column table.</returns>
        public virtual System.Collections.IList GetDataList(CommonCommand conditionCommand)
        {
            return GetDataList(conditionCommand, this.TransactionManager.DefaultTransaction);
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <returns>data object column table.</returns>
        public virtual System.Collections.IList GetDataList(string[] columnNames, CommonCommand conditionCommand)
        {
            return GetDataList(columnNames, conditionCommand, this.TransactionManager.DefaultTransaction);
        }

        #region Paging Operation 
        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <returns>data object column table.</returns>
        public virtual System.Collections.IList GetDataList(int startRecord, int maxRecords)
        {
            return GetDataList(startRecord, maxRecords, this.TransactionManager.DefaultTransaction);
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <returns>data object column table.</returns>
        public virtual System.Collections.IList GetDataList(string[] columnNames, int startRecord, int maxRecords)
        {
            return GetDataList(columnNames, startRecord, maxRecords, this.TransactionManager.DefaultTransaction);
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <returns>data object column table.</returns>
        public virtual System.Collections.IList GetDataList(CommonCommand conditionCommand, int startRecord, int maxRecords)
        {
            return GetDataList(conditionCommand, startRecord, maxRecords, this.TransactionManager.DefaultTransaction);
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <returns>data object column table.</returns>
        public virtual System.Collections.IList GetDataList(string[] columnNames, CommonCommand conditionCommand, int startRecord, int maxRecords)
        {
            return GetDataList(columnNames, conditionCommand, startRecord, maxRecords, this.TransactionManager.DefaultTransaction);
        }
        #endregion

        #region Enumerator
        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <returns>the enumerator of data objects.</returns>
        public virtual System.Collections.IEnumerable GetEnumerator()
        {
            return GetEnumerator(this.TransactionManager.DefaultTransaction);
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <returns>the enumerator of data objects.</returns>
        public virtual System.Collections.IEnumerable GetEnumerator(string[] columnNames)
        {
            return GetEnumerator(columnNames, this.TransactionManager.DefaultTransaction);
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <returns>the enumerator of data objects.</returns>
        public virtual System.Collections.IEnumerable GetEnumerator(CommonCommand conditionCommand)
        {
            return GetEnumerator(conditionCommand, this.TransactionManager.DefaultTransaction);
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <returns>the enumerator of data objects.</returns>
        public virtual System.Collections.IEnumerable GetEnumerator(string[] columnNames, CommonCommand conditionCommand)
        {
            return GetEnumerator(columnNames, conditionCommand, this.TransactionManager.DefaultTransaction);
        }

        #region Paging Operation 
        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <returns>the enumerator of data objects.</returns>
        public virtual System.Collections.IEnumerable GetEnumerator(int startRecord, int maxRecords)
        {
            return GetEnumerator(startRecord, maxRecords, this.TransactionManager.DefaultTransaction);
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <returns>the enumerator of data objects.</returns>
        public virtual System.Collections.IEnumerable GetEnumerator(string[] columnNames, int startRecord, int maxRecords)
        {
            return GetEnumerator(columnNames, startRecord, maxRecords, this.TransactionManager.DefaultTransaction);
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <returns>the enumerator of data objects.</returns>
        public virtual System.Collections.IEnumerable GetEnumerator(CommonCommand conditionCommand, int startRecord, int maxRecords)
        {
            return GetEnumerator(conditionCommand, startRecord, maxRecords, this.TransactionManager.DefaultTransaction);
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <returns>the enumerator of data objects.</returns>
        public virtual System.Collections.IEnumerable GetEnumerator(string[] columnNames, CommonCommand conditionCommand, int startRecord, int maxRecords)
        {
            return GetEnumerator(columnNames, conditionCommand, startRecord, maxRecords, this.TransactionManager.DefaultTransaction);
        }
        #endregion
        #endregion
        #endregion
        #endregion
        #region Transaction
        /// <summary>
        /// Fill Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>The result of execute command.</returns>
        public virtual int Fill(object dataObject, object[] primaryKeys, string transactionID)
        {
            return this.Fill(dataObject, primaryKeys, this.TransactionManager.GetTransaction(transactionID));
        }

        /// <summary>
        /// Fill Data object.
        /// </summary>
        /// <param name="dataObject">has primary key value Data object.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>The result of execute command.</returns>
        public virtual int Fill(object dataObject, string transactionID)
        {
            return this.Fill(dataObject, this.TransactionManager.GetTransaction(transactionID));
        }

        /// <summary>
        /// Fill Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>The result of execute command.</returns>
        public virtual int Fill(object dataObject, object[] primaryKeys, string[] columnNames, string transactionID)
        {
            return this.Fill(dataObject, primaryKeys, columnNames, this.TransactionManager.GetTransaction(transactionID));
        }

        /// <summary>
        /// Fill Data object.
        /// </summary>
        /// <param name="dataObject">has primary key value Data object.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>The result of execute command.</returns>
        public virtual int Fill(object dataObject, string[] columnNames, string transactionID)
        {
            return this.Fill(dataObject, columnNames, this.TransactionManager.GetTransaction(transactionID));
        }

        /// <summary>
        /// Gets Data object.
        /// </summary>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>Data object.</returns>
        public virtual object GetData(object[] primaryKeys, string transactionID)
        {
            return this.GetData(primaryKeys, this.TransactionManager.GetTransaction(transactionID));
        }

        /// <summary>
        /// Gets Data object.
        /// </summary>
        /// <param name="dataObject">has primary key value Data object.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>Data object.</returns>
        public virtual object GetData(object dataObject, string transactionID)
        {
            return this.GetData(dataObject, this.TransactionManager.GetTransaction(transactionID));
        }

        /// <summary>
        /// Gets Data object.
        /// </summary>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>Data object.</returns>
        public virtual object GetData(object[] primaryKeys, string[] columnNames, string transactionID)
        {
            return this.GetData(primaryKeys, columnNames, this.TransactionManager.GetTransaction(transactionID));
        }

        /// <summary>
        /// Gets Data object.
        /// </summary>
        /// <param name="dataObject">has primary key value Data object.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>Data object.</returns>
        public virtual object GetData(object dataObject, string[] columnNames, string transactionID)
        {
            return this.GetData(dataObject, columnNames, this.TransactionManager.GetTransaction(transactionID));
        }

        /// <summary>
        /// Insert Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int Insert(object dataObject, string transactionID)
        {
            return this.Insert(dataObject, this.TransactionManager.GetTransaction(transactionID));
        }

        /// <summary>
        /// Insert Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int Insert(object dataObject, string[] columnNames, string transactionID)
        {
            return this.Insert(dataObject, columnNames, this.TransactionManager.GetTransaction(transactionID));
        }

        /// <summary>
        /// Delete Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int Delete(object dataObject, string transactionID)
        {
            return this.Delete(dataObject, this.TransactionManager.GetTransaction(transactionID));
        }

        /// <summary>
        /// Delete Data object.
        /// </summary>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int Delete(object[] primaryKeys, string transactionID)
        {
            return this.Delete(primaryKeys, this.TransactionManager.GetTransaction(transactionID));
        }

        /// <summary>
        /// Update Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int Update(object dataObject, string transactionID)
        {
            return this.Update(dataObject, this.TransactionManager.GetTransaction(transactionID));
        }

        /// <summary>
        /// Update Data object.
        /// </summary>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="dataObject">Data object.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int Update(object[] primaryKeys, object dataObject, string transactionID)
        {
            return this.Update(primaryKeys, dataObject, this.TransactionManager.GetTransaction(transactionID));
        }

        /// <summary>
        /// Update Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int Update(object dataObject, string[] columnNames, string transactionID)
        {
            return this.Update(dataObject, columnNames, this.TransactionManager.GetTransaction(transactionID));
        }

        /// <summary>
        /// Update Data object.
        /// </summary>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="dataObject">Data object.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int Update(object[] primaryKeys, object dataObject, string[] columnNames, string transactionID)
        {
            return this.Update(primaryKeys, dataObject, columnNames, this.TransactionManager.GetTransaction(transactionID));
        }

        /// <summary>
        /// Check data object by primary key.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>If exists then return true, otherwise return false.</returns>
        public virtual bool Exists(object dataObject, string transactionID)
        {
            return this.Exists(dataObject, this.TransactionManager.GetTransaction(transactionID));
        }

        /// <summary>
        /// Check data object by primary key.
        /// </summary>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>If exists then return true, otherwise return false.</returns>
        public virtual bool Exists(object[] primaryKeys, string transactionID)
        {
            return this.Exists(primaryKeys, this.TransactionManager.GetTransaction(transactionID));
        }

        /// <summary>
        /// Save Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int Save(object dataObject, string transactionID)
        {
            return this.Save(dataObject, this.TransactionManager.GetTransaction(transactionID));
        }

        /// <summary>
        /// Save Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int Save(object dataObject, string[] columnNames, string transactionID)
        {
            return this.Save(dataObject, columnNames, this.TransactionManager.GetTransaction(transactionID));
        }

        #region Batch Operation
        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>data object column table.</returns>
        public virtual System.Collections.IList GetDataList(string transactionID)
        {
            return GetDataList(this.TransactionManager.GetTransaction(transactionID));
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>data object column table.</returns>
        public virtual System.Collections.IList GetDataList(string[] columnNames, string transactionID)
        {
            return GetDataList(columnNames, this.TransactionManager.GetTransaction(transactionID));
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>data object column table.</returns>
        public virtual System.Collections.IList GetDataList(CommonCommand conditionCommand, string transactionID)
        {
            return GetDataList(conditionCommand, this.TransactionManager.GetTransaction(transactionID));
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>data object column table.</returns>
        public virtual System.Collections.IList GetDataList(string[] columnNames, CommonCommand conditionCommand, string transactionID)
        {
            return GetDataList(columnNames, conditionCommand, this.TransactionManager.GetTransaction(transactionID));
        }

        #region Paging Operation 
        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>data object column table.</returns>
        public virtual System.Collections.IList GetDataList(int startRecord, int maxRecords, string transactionID)
        {
            return GetDataList(startRecord, maxRecords, this.TransactionManager.GetTransaction(transactionID));
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>data object column table.</returns>
        public virtual System.Collections.IList GetDataList(string[] columnNames, int startRecord, int maxRecords, string transactionID)
        {
            return GetDataList(columnNames, startRecord, maxRecords, this.TransactionManager.GetTransaction(transactionID));
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>data object column table.</returns>
        public virtual System.Collections.IList GetDataList(CommonCommand conditionCommand, int startRecord, int maxRecords, string transactionID)
        {
            return GetDataList(conditionCommand, startRecord, maxRecords, this.TransactionManager.GetTransaction(transactionID));
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>data object column table.</returns>
        public virtual System.Collections.IList GetDataList(string[] columnNames, CommonCommand conditionCommand, int startRecord, int maxRecords, string transactionID)
        {
            return GetDataList(columnNames, conditionCommand, startRecord, maxRecords, this.TransactionManager.GetTransaction(transactionID));
        }
        #endregion

        #region 迭代器
        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>the enumerator of data objects.</returns>
        public virtual System.Collections.IEnumerable GetEnumerator(string transactionID)
        {
            return GetEnumerator(this.TransactionManager.GetTransaction(transactionID));
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>the enumerator of data objects.</returns>
        public virtual System.Collections.IEnumerable GetEnumerator(string[] columnNames, string transactionID)
        {
            return GetEnumerator(columnNames, this.TransactionManager.GetTransaction(transactionID));
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>the enumerator of data objects.</returns>
        public virtual System.Collections.IEnumerable GetEnumerator(CommonCommand conditionCommand, string transactionID)
        {
            return GetEnumerator(conditionCommand, this.TransactionManager.GetTransaction(transactionID));
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>the enumerator of data objects.</returns>
        public virtual System.Collections.IEnumerable GetEnumerator(string[] columnNames, CommonCommand conditionCommand, string transactionID)
        {
            return GetEnumerator(columnNames, conditionCommand, this.TransactionManager.GetTransaction(transactionID));
        }

        #region Paging Operation 
        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>the enumerator of data objects.</returns>
        public virtual System.Collections.IEnumerable GetEnumerator(int startRecord, int maxRecords, string transactionID)
        {
            return GetEnumerator(startRecord, maxRecords, this.TransactionManager.GetTransaction(transactionID));
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>the enumerator of data objects.</returns>
        public virtual System.Collections.IEnumerable GetEnumerator(string[] columnNames, int startRecord, int maxRecords, string transactionID)
        {
            return GetEnumerator(columnNames, startRecord, maxRecords, this.TransactionManager.GetTransaction(transactionID));
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>the enumerator of data objects.</returns>
        public virtual System.Collections.IEnumerable GetEnumerator(CommonCommand conditionCommand, int startRecord, int maxRecords, string transactionID)
        {
            return GetEnumerator(conditionCommand, startRecord, maxRecords, this.TransactionManager.GetTransaction(transactionID));
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>the enumerator of data objects.</returns>
        public virtual System.Collections.IEnumerable GetEnumerator(string[] columnNames, CommonCommand conditionCommand, int startRecord, int maxRecords, string transactionID)
        {
            return GetEnumerator(columnNames, conditionCommand, startRecord, maxRecords, this.TransactionManager.GetTransaction(transactionID));
        }
        #endregion
        #endregion
        #endregion
        #endregion

        #region Extension Functions
        #region Common Methods
        /// <summary>
        /// Fill Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="primaryKey">The value of primary key.</param>
        /// <returns>The result of execute command.</returns>
        public virtual int FillByPrimaryKey(object dataObject, object primaryKey)
        {
            return this.Fill(dataObject, new object[] { primaryKey });
        }

        /// <summary>
        /// Fill Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <returns>The result of execute command.</returns>
        public virtual int FillByPrimaryKey(object dataObject, object primaryKey, string[] columnNames)
        {
            return this.Fill(dataObject, new object[] { primaryKey }, columnNames);
        }

        /// <summary>
        /// Gets Data object.
        /// </summary>
        /// <param name="primaryKey">The value of primary key.</param>
        /// <returns>Data object.</returns>
        public virtual object GetDataByPrimaryKey(object primaryKey)
        {
            return this.GetData(new object[] { primaryKey });
        }

        /// <summary>
        /// Gets Data object.
        /// </summary>
        /// <param name="primaryKey">The value of primary key.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <returns>Data object.</returns>
        public virtual object GetDataByPrimaryKey(object primaryKey, string[] columnNames)
        {
            return this.GetData(new object[] { primaryKey }, columnNames);
        }

        /// <summary>
        /// Delete Data object.
        /// </summary>
        /// <param name="primaryKey">The value of primary key.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int DeleteByPrimaryKey(object primaryKey)
        {
            return this.Delete(new object[] { primaryKey });
        }

        /// <summary>
        /// Update Data object.
        /// </summary>
        /// <param name="primaryKey">The value of primary key.</param>
        /// <param name="dataObject">Data object.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int UpdateByPrimaryKey(object primaryKey, object dataObject)
        {
            return this.Update(new object[] { primaryKey }, dataObject);
        }

        /// <summary>
        /// Update Data object.
        /// </summary>
        /// <param name="primaryKey">The value of primary key.</param>
        /// <param name="dataObject">Data object.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int UpdateByPrimaryKey(object primaryKey, object dataObject, string[] columnNames)
        {
            return this.Update(new object[] { primaryKey }, dataObject, columnNames);
        }

        /// <summary>
        /// Check data object by primary key.
        /// </summary>
        /// <param name="primaryKey">The value of primary key.</param>
        /// <returns>If exists then return true, otherwise return false.</returns>
        public virtual bool ExistsByPrimaryKey(object primaryKey)
        {
            return this.Exists(new object[] { primaryKey });
        }

        /// <summary>
        /// Gets Data object.
        /// </summary>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <returns>Data object.</returns>
        public virtual object GetDataByCondition(CommonCommand conditionCommand)
        {
            System.Collections.IList dataList = GetDataList(conditionCommand, 0, 1);
            if (dataList.Count > 0)
            {
                return dataList[0];
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// Gets Data object.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <returns>Data object.</returns>
        public virtual object GetDataByCondition(string[] columnNames, CommonCommand conditionCommand)
        {
            System.Collections.IList dataList = GetDataList(columnNames, conditionCommand, 0, 1);
            if (dataList.Count > 0)
            {
                return dataList[0];
            }
            else
            {
                return null;
            }
        }

        #region Epxression
        /// <summary>
        /// Gets Data object.
        /// </summary>
        /// <param name="conditionExpression">Condition expression</param>
        /// <returns>Data object.</returns>
        public virtual object GetDataByCondition(RaisingStudio.Data.Expressions.ConditionExpression conditionExpression)
        {
            RaisingStudio.Data.Common.Builders.Expressions.ConditionExpressionCommandBuilder conditionExpressionCommandBuilder = CreateConditionExpressionCommandBuilder(conditionExpression);
            CommonCommand conditionCommand = conditionExpressionCommandBuilder.GetExpressionCommand();
            return GetDataByCondition(conditionCommand);
        }

        public ConditionExpressionCommandBuilder CreateConditionExpressionCommandBuilder(ConditionExpression conditionExpression)
        {
            Dictionary<string, System.Data.DbType> dbTypes = GetColumnsDbTypes();
            TableExpression tableExpression = GetTableExpression();
#if !(PocketPC || Smartphone || WindowsCE)
            if (this._databaseType == DatabaseType.SHAREPOINT)
            {
                return new SharePointConditionExpressionCommandBuilder(conditionExpression, dbTypes, tableExpression);
            }
            else
            {
#endif
                return new ConditionExpressionCommandBuilder(conditionExpression, dbTypes, tableExpression);
#if !(PocketPC || Smartphone || WindowsCE)
            }
#endif
        }

        private Dictionary<string, System.Data.DbType> GetColumnsDbTypes()
        {
            // TODO: 
            return this.CommandBuilder.CommonCommandBuilder.DbTypes;
        }

        private TableExpression GetTableExpression()
        {
            return new TableExpression(this.DefaultDataTableMapping.DataSetTable);
        }

        /// <summary>
        /// Gets Data object.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionExpression">Condition expression</param>
        /// <returns>Data object.</returns>
        public virtual object GetDataByCondition(string[] columnNames, RaisingStudio.Data.Expressions.ConditionExpression conditionExpression)
        {
            RaisingStudio.Data.Common.Builders.Expressions.ConditionExpressionCommandBuilder conditionExpressionCommandBuilder = CreateConditionExpressionCommandBuilder(conditionExpression);
            CommonCommand conditionCommand = conditionExpressionCommandBuilder.GetExpressionCommand();
            return GetDataByCondition(columnNames, conditionCommand);
        }

        #region Batch Operation
        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="conditionExpression">Condition expression</param>
        /// <returns>data object column table.</returns>
        public virtual System.Collections.IList GetDataList(RaisingStudio.Data.Expressions.ConditionExpression conditionExpression)
        {
            RaisingStudio.Data.Common.Builders.Expressions.ConditionExpressionCommandBuilder conditionExpressionCommandBuilder = CreateConditionExpressionCommandBuilder(conditionExpression);
            CommonCommand conditionCommand = conditionExpressionCommandBuilder.GetExpressionCommand();
            return GetDataList(conditionCommand);
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionExpression">Condition expression</param>
        /// <returns>data object column table.</returns>
        public virtual System.Collections.IList GetDataList(string[] columnNames, RaisingStudio.Data.Expressions.ConditionExpression conditionExpression)
        {
            RaisingStudio.Data.Common.Builders.Expressions.ConditionExpressionCommandBuilder conditionExpressionCommandBuilder = CreateConditionExpressionCommandBuilder(conditionExpression);
            CommonCommand conditionCommand = conditionExpressionCommandBuilder.GetExpressionCommand();
            return GetDataList(columnNames, conditionCommand);
        }

        #region Paging Operation 
        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="conditionExpression">Condition expression</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <returns>data object column table.</returns>
        public virtual System.Collections.IList GetDataList(RaisingStudio.Data.Expressions.ConditionExpression conditionExpression, int startRecord, int maxRecords)
        {
            RaisingStudio.Data.Common.Builders.Expressions.ConditionExpressionCommandBuilder conditionExpressionCommandBuilder = CreateConditionExpressionCommandBuilder(conditionExpression);
            CommonCommand conditionCommand = conditionExpressionCommandBuilder.GetExpressionCommand();
            return GetDataList(conditionCommand, startRecord, maxRecords);
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionExpression">Condition expression</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <returns>data object column table.</returns>
        public virtual System.Collections.IList GetDataList(string[] columnNames, RaisingStudio.Data.Expressions.ConditionExpression conditionExpression, int startRecord, int maxRecords)
        {
            RaisingStudio.Data.Common.Builders.Expressions.ConditionExpressionCommandBuilder conditionExpressionCommandBuilder = CreateConditionExpressionCommandBuilder(conditionExpression);
            CommonCommand conditionCommand = conditionExpressionCommandBuilder.GetExpressionCommand();
            return GetDataList(columnNames, conditionCommand, startRecord, maxRecords);
        }
        #endregion

        #region Enumerator
        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="conditionExpression">Condition expression</param>
        /// <returns>the enumerator of data objects.</returns>
        public virtual System.Collections.IEnumerable GetEnumerator(RaisingStudio.Data.Expressions.ConditionExpression conditionExpression)
        {
            RaisingStudio.Data.Common.Builders.Expressions.ConditionExpressionCommandBuilder conditionExpressionCommandBuilder = CreateConditionExpressionCommandBuilder(conditionExpression);
            CommonCommand conditionCommand = conditionExpressionCommandBuilder.GetExpressionCommand();
            return GetEnumerator(conditionCommand);
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionExpression">Condition expression</param>
        /// <returns>the enumerator of data objects.</returns>
        public virtual System.Collections.IEnumerable GetEnumerator(string[] columnNames, RaisingStudio.Data.Expressions.ConditionExpression conditionExpression)
        {
            RaisingStudio.Data.Common.Builders.Expressions.ConditionExpressionCommandBuilder conditionExpressionCommandBuilder = CreateConditionExpressionCommandBuilder(conditionExpression);
            CommonCommand conditionCommand = conditionExpressionCommandBuilder.GetExpressionCommand();
            return GetEnumerator(columnNames, conditionCommand);
        }

        #region Paging Operation 
        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="conditionExpression">Condition expression</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <returns>the enumerator of data objects.</returns>
        public virtual System.Collections.IEnumerable GetEnumerator(RaisingStudio.Data.Expressions.ConditionExpression conditionExpression, int startRecord, int maxRecords)
        {
            RaisingStudio.Data.Common.Builders.Expressions.ConditionExpressionCommandBuilder conditionExpressionCommandBuilder = CreateConditionExpressionCommandBuilder(conditionExpression);
            CommonCommand conditionCommand = conditionExpressionCommandBuilder.GetExpressionCommand();
            return GetEnumerator(conditionCommand, startRecord, maxRecords);
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionExpression">Condition expression</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <returns>the enumerator of data objects.</returns>
        public virtual System.Collections.IEnumerable GetEnumerator(string[] columnNames, RaisingStudio.Data.Expressions.ConditionExpression conditionExpression, int startRecord, int maxRecords)
        {
            RaisingStudio.Data.Common.Builders.Expressions.ConditionExpressionCommandBuilder conditionExpressionCommandBuilder = CreateConditionExpressionCommandBuilder(conditionExpression);
            CommonCommand conditionCommand = conditionExpressionCommandBuilder.GetExpressionCommand();
            return GetEnumerator(columnNames, conditionCommand, startRecord, maxRecords);
        }
        #endregion
        #endregion
        #endregion

        #region column name Epxression
        /// <summary>
        /// Fill Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <returns>The result of execute command.</returns>
        public virtual int Fill(object dataObject, object[] primaryKeys, ColumnExpression[] columnExpressions)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return this.Fill(dataObject, primaryKeys, columnNames);
        }

        /// <summary>
        /// Fill Data object.
        /// </summary>
        /// <param name="dataObject">has primary key value Data object.</param>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <returns>The result of execute command.</returns>
        public virtual int Fill(object dataObject, ColumnExpression[] columnExpressions)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return this.Fill(dataObject, columnNames);
        }

        /// <summary>
        /// Gets Data object.
        /// </summary>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <returns>Data object.</returns>
        public virtual object GetData(object[] primaryKeys, ColumnExpression[] columnExpressions)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return this.GetData(primaryKeys, columnNames);
        }

        /// <summary>
        /// Gets Data object.
        /// </summary>
        /// <param name="dataObject">has primary key value Data object.</param>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <returns>Data object.</returns>
        public virtual object GetData(object dataObject, ColumnExpression[] columnExpressions)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return this.GetData(dataObject, columnNames);
        }

        /// <summary>
        /// Insert Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int Insert(object dataObject, ColumnExpression[] columnExpressions)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return this.Insert(dataObject, columnNames);
        }

        /// <summary>
        /// Update Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int Update(object dataObject, ColumnExpression[] columnExpressions)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return this.Update(dataObject, columnNames);
        }

        /// <summary>
        /// Update Data object.
        /// </summary>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="dataObject">Data object.</param>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int Update(object[] primaryKeys, object dataObject, ColumnExpression[] columnExpressions)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return this.Update(primaryKeys, dataObject, columnNames);
        }

        /// <summary>
        /// Save Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int Save(object dataObject, ColumnExpression[] columnExpressions)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return this.Save(dataObject, columnNames);
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <returns>data object column table.</returns>
        public virtual System.Collections.IList GetDataList(ColumnExpression[] columnExpressions)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return GetDataList(columnNames);
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <returns>data object column table.</returns>
        public virtual System.Collections.IList GetDataList(ColumnExpression[] columnExpressions, int startRecord, int maxRecords)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return GetDataList(columnNames, startRecord, maxRecords);
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <returns>the enumerator of data objects.</returns>
        public virtual System.Collections.IEnumerable GetEnumerator(ColumnExpression[] columnExpressions)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return GetEnumerator(columnNames);
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <returns>the enumerator of data objects.</returns>
        public virtual System.Collections.IEnumerable GetEnumerator(ColumnExpression[] columnExpressions, int startRecord, int maxRecords)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return GetEnumerator(columnNames, startRecord, maxRecords);
        }

        /// <summary>
        /// Fill Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <returns>The result of execute command.</returns>
        public virtual int FillByPrimaryKey(object dataObject, object primaryKey, ColumnExpression[] columnExpressions)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return this.Fill(dataObject, new object[] { primaryKey }, columnNames);
        }

        /// <summary>
        /// Gets Data object.
        /// </summary>
        /// <param name="primaryKey">The value of primary key.</param>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <returns>Data object.</returns>
        public virtual object GetDataByPrimaryKey(object primaryKey, ColumnExpression[] columnExpressions)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return this.GetData(new object[] { primaryKey }, columnNames);
        }

        /// <summary>
        /// Update Data object.
        /// </summary>
        /// <param name="primaryKey">The value of primary key.</param>
        /// <param name="dataObject">Data object.</param>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int UpdateByPrimaryKey(object primaryKey, object dataObject, ColumnExpression[] columnExpressions)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return this.Update(new object[] { primaryKey }, dataObject, columnNames);
        }

        /// <summary>
        /// Gets Data object.
        /// </summary>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <param name="conditionExpression">Condition expression</param>
        /// <returns>Data object.</returns>
        public virtual object GetDataByCondition(ColumnExpression[] columnExpressions, RaisingStudio.Data.Expressions.ConditionExpression conditionExpression)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return GetDataByCondition(columnNames, conditionExpression);
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <param name="conditionExpression">Condition expression</param>
        /// <returns>data object column table.</returns>
        public virtual System.Collections.IList GetDataList(ColumnExpression[] columnExpressions, RaisingStudio.Data.Expressions.ConditionExpression conditionExpression)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return GetDataList(columnNames, conditionExpression);
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <param name="conditionExpression">Condition expression</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <returns>data object column table.</returns>
        public virtual System.Collections.IList GetDataList(ColumnExpression[] columnExpressions, RaisingStudio.Data.Expressions.ConditionExpression conditionExpression, int startRecord, int maxRecords)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return GetDataList(columnNames, conditionExpression, startRecord, maxRecords);
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <param name="conditionExpression">Condition expression</param>
        /// <returns>the enumerator of data objects.</returns>
        public virtual System.Collections.IEnumerable GetEnumerator(ColumnExpression[] columnExpressions, RaisingStudio.Data.Expressions.ConditionExpression conditionExpression)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return GetEnumerator(columnNames, conditionExpression);
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <param name="conditionExpression">Condition expression</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <returns>the enumerator of data objects.</returns>
        public virtual System.Collections.IEnumerable GetEnumerator(ColumnExpression[] columnExpressions, RaisingStudio.Data.Expressions.ConditionExpression conditionExpression, int startRecord, int maxRecords)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return GetEnumerator(columnNames, conditionExpression, startRecord, maxRecords);
        }
        #endregion
        #endregion
        #endregion
        #region Transaction
        /// <summary>
        /// Fill Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="primaryKey">The value of primary key.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>The result of execute command.</returns>
        public virtual int FillByPrimaryKey(object dataObject, object primaryKey, string transactionID)
        {
            return this.Fill(dataObject, new object[] { primaryKey }, transactionID);
        }

        /// <summary>
        /// Fill Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>The result of execute command.</returns>
        public virtual int FillByPrimaryKey(object dataObject, object primaryKey, string[] columnNames, string transactionID)
        {
            return this.Fill(dataObject, new object[] { primaryKey }, columnNames, transactionID);
        }

        /// <summary>
        /// Gets Data object.
        /// </summary>
        /// <param name="primaryKey">The value of primary key.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>Data object.</returns>
        public virtual object GetDataByPrimaryKey(object primaryKey, string transactionID)
        {
            return this.GetData(new object[] { primaryKey }, transactionID);
        }

        /// <summary>
        /// Gets Data object.
        /// </summary>
        /// <param name="primaryKey">The value of primary key.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>Data object.</returns>
        public virtual object GetDataByPrimaryKey(object primaryKey, string[] columnNames, string transactionID)
        {
            return this.GetData(new object[] { primaryKey }, columnNames, transactionID);
        }

        /// <summary>
        /// Delete Data object.
        /// </summary>
        /// <param name="primaryKey">The value of primary key.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int DeleteByPrimaryKey(object primaryKey, string transactionID)
        {
            return this.Delete(new object[] { primaryKey }, transactionID);
        }

        /// <summary>
        /// Update Data object.
        /// </summary>
        /// <param name="primaryKey">The value of primary key.</param>
        /// <param name="dataObject">Data object.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int UpdateByPrimaryKey(object primaryKey, object dataObject, string transactionID)
        {
            return this.Update(new object[] { primaryKey }, dataObject, transactionID);
        }

        /// <summary>
        /// Update Data object.
        /// </summary>
        /// <param name="primaryKey">The value of primary key.</param>
        /// <param name="dataObject">Data object.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int UpdateByPrimaryKey(object primaryKey, object dataObject, string[] columnNames, string transactionID)
        {
            return this.Update(new object[] { primaryKey }, dataObject, columnNames, transactionID);
        }

        /// <summary>
        /// Check data object by primary key.
        /// </summary>
        /// <param name="primaryKey">The value of primary key.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>If exists then return true, otherwise return false.</returns>
        public virtual bool ExistsByPrimaryKey(object primaryKey, string transactionID)
        {
            return this.Exists(new object[] { primaryKey }, transactionID);
        }

        /// <summary>
        /// Gets Data object.
        /// </summary>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>Data object.</returns>
        public virtual object GetDataByCondition(CommonCommand conditionCommand, string transactionID)
        {
            System.Collections.IList dataList = GetDataList(conditionCommand, 0, 1, transactionID);
            if (dataList.Count > 0)
            {
                return dataList[0];
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// Gets Data object.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>Data object.</returns>
        public virtual object GetDataByCondition(string[] columnNames, CommonCommand conditionCommand, string transactionID)
        {
            System.Collections.IList dataList = GetDataList(columnNames, conditionCommand, 0, 1, transactionID);
            if (dataList.Count > 0)
            {
                return dataList[0];
            }
            else
            {
                return null;
            }
        }

        #region Epxression
        /// <summary>
        /// Gets Data object.
        /// </summary>
        /// <param name="conditionExpression">Condition expression</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>Data object.</returns>
        public virtual object GetDataByCondition(RaisingStudio.Data.Expressions.ConditionExpression conditionExpression, string transactionID)
        {
            RaisingStudio.Data.Common.Builders.Expressions.ConditionExpressionCommandBuilder conditionExpressionCommandBuilder = CreateConditionExpressionCommandBuilder(conditionExpression);
            CommonCommand conditionCommand = conditionExpressionCommandBuilder.GetExpressionCommand();
            return GetDataByCondition(conditionCommand, transactionID);
        }

        /// <summary>
        /// Gets Data object.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionExpression">Condition expression</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>Data object.</returns>
        public virtual object GetDataByCondition(string[] columnNames, RaisingStudio.Data.Expressions.ConditionExpression conditionExpression, string transactionID)
        {
            RaisingStudio.Data.Common.Builders.Expressions.ConditionExpressionCommandBuilder conditionExpressionCommandBuilder = CreateConditionExpressionCommandBuilder(conditionExpression);
            CommonCommand conditionCommand = conditionExpressionCommandBuilder.GetExpressionCommand();
            return GetDataByCondition(columnNames, conditionCommand, transactionID);
        }

        #region Batch Operation
        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="conditionExpression">Condition expression</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>data object column table.</returns>
        public virtual System.Collections.IList GetDataList(RaisingStudio.Data.Expressions.ConditionExpression conditionExpression, string transactionID)
        {
            RaisingStudio.Data.Common.Builders.Expressions.ConditionExpressionCommandBuilder conditionExpressionCommandBuilder = CreateConditionExpressionCommandBuilder(conditionExpression);
            CommonCommand conditionCommand = conditionExpressionCommandBuilder.GetExpressionCommand();
            return GetDataList(conditionCommand, transactionID);
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionExpression">Condition expression</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>data object column table.</returns>
        public virtual System.Collections.IList GetDataList(string[] columnNames, RaisingStudio.Data.Expressions.ConditionExpression conditionExpression, string transactionID)
        {
            RaisingStudio.Data.Common.Builders.Expressions.ConditionExpressionCommandBuilder conditionExpressionCommandBuilder = CreateConditionExpressionCommandBuilder(conditionExpression);
            CommonCommand conditionCommand = conditionExpressionCommandBuilder.GetExpressionCommand();
            return GetDataList(columnNames, conditionCommand, transactionID);
        }

        #region Paging Operation 
        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="conditionExpression">Condition expression</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>data object column table.</returns>
        public virtual System.Collections.IList GetDataList(RaisingStudio.Data.Expressions.ConditionExpression conditionExpression, int startRecord, int maxRecords, string transactionID)
        {
            RaisingStudio.Data.Common.Builders.Expressions.ConditionExpressionCommandBuilder conditionExpressionCommandBuilder = CreateConditionExpressionCommandBuilder(conditionExpression);
            CommonCommand conditionCommand = conditionExpressionCommandBuilder.GetExpressionCommand();
            return GetDataList(conditionCommand, startRecord, maxRecords, transactionID);
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionExpression">Condition expression</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>data object column table.</returns>
        public virtual System.Collections.IList GetDataList(string[] columnNames, RaisingStudio.Data.Expressions.ConditionExpression conditionExpression, int startRecord, int maxRecords, string transactionID)
        {
            RaisingStudio.Data.Common.Builders.Expressions.ConditionExpressionCommandBuilder conditionExpressionCommandBuilder = CreateConditionExpressionCommandBuilder(conditionExpression);
            CommonCommand conditionCommand = conditionExpressionCommandBuilder.GetExpressionCommand();
            return GetDataList(columnNames, conditionCommand, startRecord, maxRecords, transactionID);
        }
        #endregion

        #region 迭代器
        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="conditionExpression">Condition expression</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>the enumerator of data objects.</returns>
        public virtual System.Collections.IEnumerable GetEnumerator(RaisingStudio.Data.Expressions.ConditionExpression conditionExpression, string transactionID)
        {
            RaisingStudio.Data.Common.Builders.Expressions.ConditionExpressionCommandBuilder conditionExpressionCommandBuilder = CreateConditionExpressionCommandBuilder(conditionExpression);
            CommonCommand conditionCommand = conditionExpressionCommandBuilder.GetExpressionCommand();
            return GetEnumerator(conditionCommand, transactionID);
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionExpression">Condition expression</param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>the enumerator of data objects.</returns>
        public virtual System.Collections.IEnumerable GetEnumerator(string[] columnNames, RaisingStudio.Data.Expressions.ConditionExpression conditionExpression, string transactionID)
        {
            RaisingStudio.Data.Common.Builders.Expressions.ConditionExpressionCommandBuilder conditionExpressionCommandBuilder = CreateConditionExpressionCommandBuilder(conditionExpression);
            CommonCommand conditionCommand = conditionExpressionCommandBuilder.GetExpressionCommand();
            return GetEnumerator(columnNames, conditionCommand, transactionID);
        }

        #region Paging Operation 
        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="conditionExpression">Condition expression</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>the enumerator of data objects.</returns>
        public virtual System.Collections.IEnumerable GetEnumerator(RaisingStudio.Data.Expressions.ConditionExpression conditionExpression, int startRecord, int maxRecords, string transactionID)
        {
            RaisingStudio.Data.Common.Builders.Expressions.ConditionExpressionCommandBuilder conditionExpressionCommandBuilder = CreateConditionExpressionCommandBuilder(conditionExpression);
            CommonCommand conditionCommand = conditionExpressionCommandBuilder.GetExpressionCommand();
            return GetEnumerator(conditionCommand, startRecord, maxRecords, transactionID);
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionExpression">Condition expression</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <param name="transactionID">The ID of transaction.</param>
        /// <returns>the enumerator of data objects.</returns>
        public virtual System.Collections.IEnumerable GetEnumerator(string[] columnNames, RaisingStudio.Data.Expressions.ConditionExpression conditionExpression, int startRecord, int maxRecords, string transactionID)
        {
            RaisingStudio.Data.Common.Builders.Expressions.ConditionExpressionCommandBuilder conditionExpressionCommandBuilder = CreateConditionExpressionCommandBuilder(conditionExpression);
            CommonCommand conditionCommand = conditionExpressionCommandBuilder.GetExpressionCommand();
            return GetEnumerator(columnNames, conditionCommand, startRecord, maxRecords, transactionID);
        }
        #endregion
        #endregion
        #endregion

        #region column name Epxression
        /// <summary>
        /// Fill Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <returns>The result of execute command.</returns>
        public virtual int Fill(object dataObject, object[] primaryKeys, ColumnExpression[] columnExpressions, string transactionID)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return this.Fill(dataObject, primaryKeys, columnNames, transactionID);
        }

        /// <summary>
        /// Fill Data object.
        /// </summary>
        /// <param name="dataObject">has primary key value Data object.</param>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <returns>The result of execute command.</returns>
        public virtual int Fill(object dataObject, ColumnExpression[] columnExpressions, string transactionID)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return this.Fill(dataObject, columnNames, transactionID);
        }

        /// <summary>
        /// Gets Data object.
        /// </summary>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <returns>Data object.</returns>
        public virtual object GetData(object[] primaryKeys, ColumnExpression[] columnExpressions, string transactionID)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return this.GetData(primaryKeys, columnNames, transactionID);
        }

        /// <summary>
        /// Gets Data object.
        /// </summary>
        /// <param name="dataObject">has primary key value Data object.</param>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <returns>Data object.</returns>
        public virtual object GetData(object dataObject, ColumnExpression[] columnExpressions, string transactionID)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return this.GetData(dataObject, columnNames, transactionID);
        }

        /// <summary>
        /// Insert Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int Insert(object dataObject, ColumnExpression[] columnExpressions, string transactionID)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return this.Insert(dataObject, columnNames, transactionID);
        }

        /// <summary>
        /// Update Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int Update(object dataObject, ColumnExpression[] columnExpressions, string transactionID)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return this.Update(dataObject, columnNames, transactionID);
        }

        /// <summary>
        /// Update Data object.
        /// </summary>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="dataObject">Data object.</param>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int Update(object[] primaryKeys, object dataObject, ColumnExpression[] columnExpressions, string transactionID)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return this.Update(primaryKeys, dataObject, columnNames, transactionID);
        }

        /// <summary>
        /// Save Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int Save(object dataObject, ColumnExpression[] columnExpressions, string transactionID)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return this.Save(dataObject, columnNames, transactionID);
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <returns>data object column table.</returns>
        public virtual System.Collections.IList GetDataList(ColumnExpression[] columnExpressions, string transactionID)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return GetDataList(columnNames, transactionID);
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <returns>data object column table.</returns>
        public virtual System.Collections.IList GetDataList(ColumnExpression[] columnExpressions, int startRecord, int maxRecords, string transactionID)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return GetDataList(columnNames, startRecord, maxRecords, transactionID);
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <returns>the enumerator of data objects.</returns>
        public virtual System.Collections.IEnumerable GetEnumerator(ColumnExpression[] columnExpressions, string transactionID)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return GetEnumerator(columnNames, transactionID);
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <returns>the enumerator of data objects.</returns>
        public virtual System.Collections.IEnumerable GetEnumerator(ColumnExpression[] columnExpressions, int startRecord, int maxRecords, string transactionID)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return GetEnumerator(columnNames, startRecord, maxRecords, transactionID);
        }

        /// <summary>
        /// Fill Data object.
        /// </summary>
        /// <param name="dataObject">Data object.</param>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <returns>The result of execute command.</returns>
        public virtual int FillByPrimaryKey(object dataObject, object primaryKey, ColumnExpression[] columnExpressions, string transactionID)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return this.Fill(dataObject, new object[] { primaryKey }, columnNames, transactionID);
        }

        /// <summary>
        /// Gets Data object.
        /// </summary>
        /// <param name="primaryKey">The value of primary key.</param>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <returns>Data object.</returns>
        public virtual object GetDataByPrimaryKey(object primaryKey, ColumnExpression[] columnExpressions, string transactionID)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return this.GetData(new object[] { primaryKey }, columnNames, transactionID);
        }

        /// <summary>
        /// Update Data object.
        /// </summary>
        /// <param name="primaryKey">The value of primary key.</param>
        /// <param name="dataObject">Data object.</param>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <returns>The count of rows that updated.</returns>
        public virtual int UpdateByPrimaryKey(object primaryKey, object dataObject, ColumnExpression[] columnExpressions, string transactionID)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return this.Update(new object[] { primaryKey }, dataObject, columnNames, transactionID);
        }

        /// <summary>
        /// Gets Data object.
        /// </summary>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <param name="conditionExpression">Condition expression</param>
        /// <returns>Data object.</returns>
        public virtual object GetDataByCondition(ColumnExpression[] columnExpressions, RaisingStudio.Data.Expressions.ConditionExpression conditionExpression, string transactionID)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return GetDataByCondition(columnNames, conditionExpression, transactionID);
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <param name="conditionExpression">Condition expression</param>
        /// <returns>data object column table.</returns>
        public virtual System.Collections.IList GetDataList(ColumnExpression[] columnExpressions, RaisingStudio.Data.Expressions.ConditionExpression conditionExpression, string transactionID)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return GetDataList(columnNames, conditionExpression, transactionID);
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <param name="conditionExpression">Condition expression</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <returns>data object column table.</returns>
        public virtual System.Collections.IList GetDataList(ColumnExpression[] columnExpressions, RaisingStudio.Data.Expressions.ConditionExpression conditionExpression, int startRecord, int maxRecords, string transactionID)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return GetDataList(columnNames, conditionExpression, startRecord, maxRecords, transactionID);
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <param name="conditionExpression">Condition expression</param>
        /// <returns>the enumerator of data objects.</returns>
        public virtual System.Collections.IEnumerable GetEnumerator(ColumnExpression[] columnExpressions, RaisingStudio.Data.Expressions.ConditionExpression conditionExpression, string transactionID)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return GetEnumerator(columnNames, conditionExpression, transactionID);
        }

        /// <summary>
        /// Gets the enumerator of data objects.
        /// </summary>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <param name="conditionExpression">Condition expression</param>
        /// <param name="startRecord">The zero-based record number to start with. </param>
        /// <param name="maxRecords">The maximum number of records to retrieve. </param>
        /// <returns>the enumerator of data objects.</returns>
        public virtual System.Collections.IEnumerable GetEnumerator(ColumnExpression[] columnExpressions, RaisingStudio.Data.Expressions.ConditionExpression conditionExpression, int startRecord, int maxRecords, string transactionID)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return GetEnumerator(columnNames, conditionExpression, startRecord, maxRecords, transactionID);
        }
        #endregion
        #endregion
        #endregion
        #endregion

        private int FillDataObjectList(System.Data.IDbCommand command, System.Collections.IList dataObjectList, System.Collections.IList columnNames, IObjectAccessor objectAccess, Dictionary<string, DataConverter> propertyConverters, Dictionary<string, string> sourceNames, Dictionary<string, System.Data.DbType> dbTypes)
        {
            WriteLog(command);
            System.Data.IDataReader dataReader = RaisingStudio.Data.Common.Database.ExecuteReaderCommand(command);
            return FillDataObjectList(dataReader, dataObjectList, columnNames, objectAccess, propertyConverters, sourceNames, dbTypes);
        }

        private int FillDataObjectList(System.Data.IDbCommand command, System.Collections.IList dataObjectList, System.Collections.IList columnNames, IDataObjectProxy proxy, Dictionary<string, DataConverter> propertyConverters, Dictionary<string, string> sourceNames, Dictionary<string, System.Data.DbType> dbTypes)
        {
            WriteLog(command);
            System.Data.IDataReader dataReader = RaisingStudio.Data.Common.Database.ExecuteReaderCommand(command);
            return FillDataObjectList(dataReader, dataObjectList, columnNames, proxy, propertyConverters, sourceNames, dbTypes);
        }

        private int FillDataObjectList(System.Data.IDataReader dataReader, System.Collections.IList dataObjectList, System.Collections.IList columnNames, IObjectAccessor objectAccess, Dictionary<string, DataConverter> propertyConverters, Dictionary<string, string> sourceNames, Dictionary<string, System.Data.DbType> dbTypes)
        {
            int index = 0;
            try
            {
                while (dataReader.Read())
                {
                    object dataObject = CreateDataObject();
                    SetDataObjectValues(dataReader, columnNames, objectAccess, propertyConverters, sourceNames, dbTypes, dataObject);
                    dataObjectList.Add(dataObject);
                    index++;
                }
            }
            finally
            {
                if (dataReader != null)
                {
                    dataReader.Close();
                }
            }
            return index;
        }


        public void SetDataObjectValues(System.Data.IDataReader dataReader, System.Collections.IList columnNames, IObjectAccessor objectAccess, Dictionary<string, DataConverter> propertyConverters, Dictionary<string, string> sourceNames, Dictionary<string, System.Data.DbType> dbTypes, object dataObject)
        {
            foreach (string columnName in columnNames)
            {
                object value = DataItemAdapter.GetDataReaderValue(dataReader, sourceNames[columnName], dbTypes[columnName]);
                if (value == System.DBNull.Value)
                {
                    objectAccess.SetValue(dataObject, columnName, null);
                }
                else
                {
                    if (propertyConverters[columnName] != null)
                    {
                        value = propertyConverters[columnName](value);
                    }
                    objectAccess.SetValue(dataObject, columnName, value);
                }
            }
        }

        public int FillDataObjectList(System.Data.IDataReader dataReader, System.Collections.IList dataObjectList, System.Collections.IList columnNames, IDataObjectProxy proxy, Dictionary<string, DataConverter> propertyConverters, Dictionary<string, string> sourceNames, Dictionary<string, System.Data.DbType> dbTypes)
        {
            int index = 0;
            try
            {
                while (dataReader.Read())
                {
                    object dataObject = proxy.CreateObject();
                    SetDataObjectValues(dataReader, columnNames, proxy, propertyConverters, sourceNames, dbTypes, dataObject);
                    dataObjectList.Add(dataObject);
                    index++;
                }
            }
            finally
            {
                if (dataReader != null)
                {
                    dataReader.Close();
                }
            }
            return index;
        }

        private int FillDataObjectList(System.Data.IDbCommand command, System.Collections.IList dataObjectList, System.Collections.IList columnNames, IObjectAccessor objectAccess, Dictionary<string, DataConverter> propertyConverters, Dictionary<string, string> sourceNames, Dictionary<string, System.Data.DbType> dbTypes, int startRecord, int maxRecords)
        {
            WriteLog(command);
            System.Data.IDataReader dataReader = RaisingStudio.Data.Common.Database.ExecuteReaderCommand(command);
            int index = 0;
            int count = 0;
            try
            {
                while ((dataReader.Read()) && (count < maxRecords))
                {
                    if (index >= startRecord)
                    {
                        object dataObject = CreateDataObject();
                        foreach (string columnName in columnNames)
                        {
                            object value = DataItemAdapter.GetDataReaderValue(dataReader, sourceNames[columnName], dbTypes[columnName]);
                            if (value == System.DBNull.Value)
                            {
                                objectAccess.SetValue(dataObject, columnName, null);
                            }
                            else
                            {
                                if (propertyConverters[columnName] != null)
                                {
                                    value = propertyConverters[columnName](value);
                                }
                                objectAccess.SetValue(dataObject, columnName, value);
                            }
                        }
                        dataObjectList.Add(dataObject);
                        count++;
                    }
                    index++;
                }
            }
            finally
            {
                if (dataReader != null)
                {
                    dataReader.Close();
                }
            }
            return count;
        }

        private System.Collections.IEnumerable GetEnumerator(System.Data.IDbCommand command, System.Collections.IList columnNames, IObjectAccessor objectAccess, Dictionary<string, DataConverter> propertyConverters, Dictionary<string, string> sourceNames, Dictionary<string, System.Data.DbType> dbTypes)
        {
            WriteLog(command);
            System.Data.IDataReader dataReader = RaisingStudio.Data.Common.Database.ExecuteReaderCommand(command);
            return GetEnumerator(dataReader, columnNames, objectAccess, propertyConverters, sourceNames, dbTypes);
        }

        private System.Collections.IEnumerable GetEnumerator(System.Data.IDbCommand command, System.Collections.IList columnNames, IDataObjectProxy proxy, Dictionary<string, DataConverter> propertyConverters, Dictionary<string, string> sourceNames, Dictionary<string, System.Data.DbType> dbTypes)
        {
            WriteLog(command);
            System.Data.IDataReader dataReader = RaisingStudio.Data.Common.Database.ExecuteReaderCommand(command);
            return GetEnumerator(dataReader, columnNames, proxy, propertyConverters, sourceNames, dbTypes);
        }

        private System.Collections.IEnumerable GetEnumerator(System.Data.IDataReader dataReader, System.Collections.IList columnNames, IObjectAccessor objectAccess, Dictionary<string, DataConverter> propertyConverters, Dictionary<string, string> sourceNames, Dictionary<string, System.Data.DbType> dbTypes)
        {
            try
            {
                while (dataReader.Read())
                {
                    object dataObject = CreateDataObject();
                    SetDataObjectValues(dataReader, columnNames, objectAccess, propertyConverters, sourceNames, dbTypes, dataObject);
                    yield return dataObject;
                }
            }
            finally
            {
                if (dataReader != null)
                {
                    dataReader.Close();
                }
            }
        }

        private System.Collections.IEnumerable GetEnumerator(System.Data.IDataReader dataReader, System.Collections.IList columnNames, IDataObjectProxy proxy, Dictionary<string, DataConverter> propertyConverters, Dictionary<string, string> sourceNames, Dictionary<string, System.Data.DbType> dbTypes)
        {
            try
            {
                while (dataReader.Read())
                {
                    object dataObject = proxy.CreateObject();
                    SetDataObjectValues(dataReader, columnNames, proxy, propertyConverters, sourceNames, dbTypes, dataObject);
                    yield return dataObject;
                }
            }
            finally
            {
                if (dataReader != null)
                {
                    dataReader.Close();
                }
            }
        }

        private System.Collections.IEnumerable GetEnumerator(System.Data.IDbCommand command, System.Collections.IList columnNames, IObjectAccessor objectAccess, Dictionary<string, DataConverter> propertyConverters, Dictionary<string, string> sourceNames, Dictionary<string, System.Data.DbType> dbTypes, int startRecord, int maxRecords)
        {
            WriteLog(command);
            System.Data.IDataReader dataReader = RaisingStudio.Data.Common.Database.ExecuteReaderCommand(command);
            int index = 0;
            int count = 0;
            try
            {
                while ((dataReader.Read()) && (count < maxRecords))
                {
                    if (index >= startRecord)
                    {
                        object dataObject = CreateDataObject();
                        SetDataObjectValues(dataReader, columnNames, objectAccess, propertyConverters, sourceNames, dbTypes, dataObject);
                        yield return dataObject;
                        count++;
                    }
                    index++;
                }
            }
            finally
            {
                if (dataReader != null)
                {
                    dataReader.Close();
                }
            }
        }


        public void BuildMappingInfo(System.Data.Common.DataTableMapping dataTableMapping, out List<string> columnNames, out IObjectAccessor objectAccess, out Dictionary<string, DataConverter> propertyConverters, out Dictionary<string, string> sourceNames, out Dictionary<string, System.Data.DbType> dbTypes)
        {
            objectAccess = GetObjectAccessor(this.dataObjectType, this.CommandBuilder.CommonCommandBuilder.DataTableDefinition.Columns);
            columnNames = new List<string>();
            propertyConverters = new Dictionary<string, DataConverter>();
            sourceNames = new Dictionary<string, string>();
            dbTypes = new Dictionary<string, System.Data.DbType>();
            foreach (System.Data.Common.DataColumnMapping dataColumnMapping in dataTableMapping.ColumnMappings)
            {
                string columnName = dataColumnMapping.DataSetColumn;
                System.Reflection.PropertyInfo propertyInfo = this.dataObjectType.GetProperty(columnName);
                columnNames.Add(columnName);

                string sourceName = dataColumnMapping.SourceColumn;
                DataColumnDefinition dataColumnDefinition = this.CommandBuilder.CommonCommandBuilder.DataTableDefinition.Columns[columnName];
                System.Data.DbType dbType = dataColumnDefinition.DbType;

                sourceNames.Add(columnName, sourceName);
                dbTypes.Add(columnName, dbType);

                propertyConverters.Add(columnName, GetDataConverter(dbType, propertyInfo.PropertyType));
            }
        }

        public void BuildMappingInfo(System.Data.Common.DataTableMapping dataTableMapping, out List<string> columnNames, IDataObjectProxy proxy, out Dictionary<string, DataConverter> propertyConverters, out Dictionary<string, string> sourceNames, out Dictionary<string, System.Data.DbType> dbTypes)
        {
            columnNames = new List<string>();
            propertyConverters = new Dictionary<string, DataConverter>();
            sourceNames = new Dictionary<string, string>();
            dbTypes = new Dictionary<string, System.Data.DbType>();
            foreach (System.Data.Common.DataColumnMapping dataColumnMapping in dataTableMapping.ColumnMappings)
            {
                string columnName = dataColumnMapping.DataSetColumn;
                columnNames.Add(columnName);

                string sourceName = dataColumnMapping.SourceColumn;
                DataColumnDefinition dataColumnDefinition = this.CommandBuilder.CommonCommandBuilder.DataTableDefinition.Columns[columnName];
                System.Data.DbType dbType = dataColumnDefinition.DbType;

                sourceNames.Add(columnName, sourceName);
                dbTypes.Add(columnName, dbType);

                propertyConverters.Add(columnName, GetDataConverter(dbType, proxy.GetPropertyType(columnName)));
            }
        }

        public void BuildMappingInfo(System.Data.Common.DataTableMapping dataTableMapping, string[] columnNames, out IObjectAccessor objectAccess, out Dictionary<string, DataConverter> propertyConverters, out Dictionary<string, string> sourceNames, out Dictionary<string, System.Data.DbType> dbTypes)
        {
            objectAccess = GetObjectAccessor(this.dataObjectType, this.CommandBuilder.CommonCommandBuilder.DataTableDefinition.Columns);
            propertyConverters = new Dictionary<string, DataConverter>();
            sourceNames = new Dictionary<string, string>();
            dbTypes = new Dictionary<string, System.Data.DbType>();
            foreach (string columnName in columnNames)
            {
                System.Reflection.PropertyInfo propertyInfo = this.dataObjectType.GetProperty(columnName);
                DataColumnDefinition dataColumnDefinition = this.CommandBuilder.CommonCommandBuilder.DataTableDefinition.Columns[columnName];
                string sourceName = RaisingStudio.Data.Common.Builders.CommonCommandBuilder.GetDataColumnSourceColumn(dataTableMapping, columnName);
                System.Data.DbType dbType = dataColumnDefinition.DbType;
                sourceNames.Add(columnName, sourceName);
                dbTypes.Add(columnName, dbType);

                propertyConverters.Add(columnName, GetDataConverter(dbType, propertyInfo.PropertyType));
            }
        }

        public void BuildMappingInfo(System.Data.Common.DataTableMapping dataTableMapping, string[] columnNames, IDataObjectProxy proxy, out Dictionary<string, DataConverter> propertyConverters, out Dictionary<string, string> sourceNames, out Dictionary<string, System.Data.DbType> dbTypes)
        {
            propertyConverters = new Dictionary<string, DataConverter>();
            sourceNames = new Dictionary<string, string>();
            dbTypes = new Dictionary<string, System.Data.DbType>();
            foreach (string columnName in columnNames)
            {
                System.Reflection.PropertyInfo propertyInfo = this.dataObjectType.GetProperty(columnName);
                DataColumnDefinition dataColumnDefinition = this.CommandBuilder.CommonCommandBuilder.DataTableDefinition.Columns[columnName];
                string sourceName = RaisingStudio.Data.Common.Builders.CommonCommandBuilder.GetDataColumnSourceColumn(dataTableMapping, columnName);
                System.Data.DbType dbType = dataColumnDefinition.DbType;
                sourceNames.Add(columnName, sourceName);
                dbTypes.Add(columnName, dbType);

                propertyConverters.Add(columnName, GetDataConverter(dbType, proxy.GetPropertyType(columnName)));
            }
        }



        public System.Collections.IEnumerable GetEnumerator(System.Data.IDataReader dataReader, List<string> columnNames, Dictionary<string, System.Reflection.PropertyInfo> propertyInfos, Dictionary<string, DataConverter> propertyConverters, Dictionary<string, string> sourceNames, Dictionary<string, System.Data.DbType> dbTypes)
        {
            try
            {
                while (dataReader.Read())
                {
                    object dataObject = CreateDataObject();
                    SetDataObjectValues(dataReader, columnNames, propertyInfos, propertyConverters, sourceNames, dbTypes, dataObject);
                    yield return dataObject;
                }
            }
            finally
            {
                if (dataReader != null)
                {
                    dataReader.Close();
                }
            }
        }
        
        public System.Collections.IEnumerable GetEnumerator(System.Data.IDataReader dataReader, List<string> columnNames, Dictionary<string, System.Reflection.PropertyInfo> propertyInfos, Dictionary<string, DataConverter> propertyConverters, Dictionary<string, string> sourceNames, Dictionary<string, System.Data.DbType> dbTypes, int startRecord, int maxRecords)
        {
            int index = 0;
            int count = 0;
            try
            {
                while ((dataReader.Read()) && (count < maxRecords))
                {
                    if (index >= startRecord)
                    {
                        object dataObject = CreateDataObject();
                        SetDataObjectValues(dataReader, columnNames, propertyInfos, propertyConverters, sourceNames, dbTypes, dataObject);
                        yield return dataObject;
                        count++;
                    }
                    index++;
                }
            }
            finally
            {
                if (dataReader != null)
                {
                    dataReader.Close();
                }
            }
        }


        public void SetDataObjectValues(System.Data.IDataReader dataReader, List<string> columnNames, Dictionary<string, System.Reflection.PropertyInfo> propertyInfos, Dictionary<string, DataConverter> propertyConverters, Dictionary<string, string> sourceNames, Dictionary<string, System.Data.DbType> dbTypes, object dataObject)
        {
            foreach (string columnName in columnNames)
            {
                string sourceName = sourceNames[columnName];
                System.Data.DbType dbType = dbTypes[columnName];
                System.Reflection.PropertyInfo propertyInfo = propertyInfos[columnName];
                if (propertyInfo != null)
                {
                    object value = DataItemAdapter.GetDataReaderValue(dataReader, sourceName, dbType);
                    if (value == System.DBNull.Value)
                    {
                        propertyInfo.SetValue(dataObject, null, null);
                    }
                    else
                    {
                        value = ConvertDataValue(dbType, propertyInfo.PropertyType, value);
                        propertyInfo.SetValue(dataObject, value, null);
                    }
                }
                else
                {
                    throw new System.MissingMemberException(string.Format("Can not find a property named {1} in type  {0}.", dataObjectType, columnName));
                }
            }
        }

        
        private int Update(object dataObject, System.Data.Common.DataTableMapping dataTableMapping, System.Data.IDbCommand command)
        {
            int columnCount = dataTableMapping.ColumnMappings.Count;
            if (UseDynamicProxy)
            {
                #region UseDynamicProxy
                System.Type dataObjectType = dataObject.GetType();
                IObjectAccessor objectAccessor = GetObjectAccessor(dataObjectType, this.DefaultDataTableMapping.ColumnMappings);
                SetParameterValues(dataObject, command, dataObjectType, columnCount, objectAccessor);
                #endregion
            }
            else
            {
                if (dataObject is IDataObjectProxy)
                {
                    #region IObjectAccessor
                    IObjectAccessor objectAccessor = dataObject as IObjectAccessor;
                    SetParameterValues(dataObject, command, dataObject as IDataObjectProxy, columnCount, objectAccessor);
                    #endregion
                }
                else
                {
                    #region Reflection
                    System.Type dataObjectType = dataObject.GetType();
                    SetParameterValues(dataObject, command, dataObjectType, columnCount);
                    #endregion
                }
            }

            if (this.TransactionManager.DefaultTransaction != null)
            {
                command.Transaction = this.TransactionManager.DefaultTransaction;
            }
            WriteLog(command);
            return RaisingStudio.Data.Common.Database.ExecuteNonQueryCommand(command);
        }

        private void SetParameterValues(object dataObject, System.Data.IDbCommand command, System.Type dataObjectType, int columnCount)
        {
            int i = 0;
            foreach (System.Data.IDbDataParameter parameter in command.Parameters)
            {
                if (!GetSourceColumnNullMapping(parameter))
                {
                    string columnName = parameter.SourceColumn;
                    System.Reflection.PropertyInfo propertyInfo = dataObjectType.GetProperty(columnName);
                    if (propertyInfo != null)
                    {
                        object value = propertyInfo.GetValue(dataObject, null);
                        if (value == null)
                        {
                            parameter.Value = System.DBNull.Value;
                        }
                        else
                        {
                            value = ConvertDataValue(propertyInfo.PropertyType, parameter.DbType, value);
                            parameter.Value = value;
                        }
                    }
                    else
                    {
                        throw new System.MissingMemberException(string.Format("Can not find a property named {1} in type  {0}.", dataObjectType, columnName));
                    }
                    i++;
                    if (i >= columnCount)
                    {
                        break;
                    }
                }
            }
        }

        private void SetParameterValues(object dataObject, System.Data.IDbCommand command, System.Type dataObjectType, int columnCount, IObjectAccessor objectAccessor)
        {
            int i = 0;
            if (objectAccessor != null)
            {
                foreach (System.Data.IDbDataParameter parameter in command.Parameters)
                {
                    if (!GetSourceColumnNullMapping(parameter))
                    {
                        string columnName = parameter.SourceColumn;
                        object value = objectAccessor.GetValue(dataObject, columnName);
                        if (value == null)
                        {
                            parameter.Value = System.DBNull.Value;
                        }
                        else
                        {
                            Type propertyType = GetDataObjectPropertyType(dataObjectType, columnName);
                            value = ConvertDataValue(propertyType, parameter.DbType, value);
                            parameter.Value = value;
                        }
                        i++;
                        if (i >= columnCount)
                        {
                            break;
                        }
                    }
                }
            }
            else
            {
                // TODO: exception.
                throw new ObjectAccessorException(string.Format("Can't get ObjectAccessor for type [{0}].", dataObjectType));
            }
        }

        private void SetParameterValues(object dataObject, System.Data.IDbCommand command, IDataObjectProxy proxy, int columnCount, IObjectAccessor objectAccessor)
        {
            int i = 0;
            if (objectAccessor != null)
            {
                foreach (System.Data.IDbDataParameter parameter in command.Parameters)
                {
                    if (!GetSourceColumnNullMapping(parameter))
                    {
                        string columnName = parameter.SourceColumn;
                        object value = objectAccessor.GetValue(dataObject, columnName);
                        if (value == null)
                        {
                            parameter.Value = System.DBNull.Value;
                        }
                        else
                        {
                            Type propertyType = proxy.GetPropertyType(columnName);
                            value = ConvertDataValue(propertyType, parameter.DbType, value);
                            parameter.Value = value;
                        }
                        i++;
                        if (i >= columnCount)
                        {
                            break;
                        }
                    }
                }
            }
            else
            {
                // TODO: exception.
                throw new ObjectAccessorException(string.Format("Can't get ObjectAccessor for type [{0}].", dataObjectType));
            }
        }


        public int UpdateByCondition(object dataObject, ConditionExpression condition)
        {
            System.Data.Common.DataTableMapping dataTableMapping = this.DefaultDataTableMapping;
            RaisingStudio.Data.Common.Builders.Expressions.ConditionExpressionCommandBuilder conditionExpressionCommandBuilder = CreateConditionExpressionCommandBuilder(condition);
            CommonCommand conditionCommand = conditionExpressionCommandBuilder.GetExpressionCommand();
            System.Data.IDbCommand command = this.CommandBuilder.GetUpdateCommand(dataTableMapping, conditionCommand);
            return Update(dataObject, dataTableMapping, command);
        }

        public int UpdateByCondition(object dataObject, CommonCommand conditionCommand)
        {
            System.Data.Common.DataTableMapping dataTableMapping = this.DefaultDataTableMapping;
            System.Data.IDbCommand command = this.CommandBuilder.GetUpdateCommand(dataTableMapping, conditionCommand);
            return Update(dataObject, dataTableMapping, command);
        }

        public int UpdateByCondition(object dataObject, ColumnExpression[] columns, ConditionExpression condition)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columns);
            System.Data.Common.DataTableMapping dataTableMapping = this.CommandBuilder.CommonCommandBuilder.GetDataTableMapping(columnNames);
            RaisingStudio.Data.Common.Builders.Expressions.ConditionExpressionCommandBuilder conditionExpressionCommandBuilder = CreateConditionExpressionCommandBuilder(condition);
            CommonCommand conditionCommand = conditionExpressionCommandBuilder.GetExpressionCommand();
            System.Data.IDbCommand command = this.CommandBuilder.GetUpdateCommand(dataTableMapping, conditionCommand);
            return Update(dataObject, dataTableMapping, command);
        }

        public int UpdateByCondition(object dataObject, ColumnExpression[] columns, CommonCommand conditionCommand)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columns);
            System.Data.Common.DataTableMapping dataTableMapping = this.CommandBuilder.CommonCommandBuilder.GetDataTableMapping(columnNames);
            System.Data.IDbCommand command = this.CommandBuilder.GetUpdateCommand(dataTableMapping, conditionCommand);
            return Update(dataObject, dataTableMapping, command);
        }

        #region Bulk operation
        public virtual int Insert(System.Collections.IList dataObjectList)
        {
            return this.Insert(dataObjectList, this.TransactionManager.DefaultTransaction);
        }

        protected virtual int Insert(System.Collections.IList dataObjectList, System.Data.IDbTransaction transaction)
        {
            System.Data.IDbCommand command = null;
            if (CacheDefalutCommand)
            {
                if (_defalutInsertCommand == null)
                {
                    _defalutInsertCommand = this.CommandBuilder.GetInsertCommand(this.DefaultDataTableMapping, false);
                }
                command = _defalutInsertCommand;
            }
            else
            {
                command = this.CommandBuilder.GetInsertCommand(this.DefaultDataTableMapping, false);
            }
            if (transaction != null)
            {
                command.Transaction = transaction;
            }
            int count = 0;
            foreach (object dataObject in dataObjectList)
            {
                SetInsertCommandParameterValues(dataObject, command);
                WriteLog(command);
                count += RaisingStudio.Data.Common.Database.ExecuteNonQueryCommand(command);
            }
            return count;
        }

        public virtual int Insert(System.Collections.IList dataObjectList, ColumnExpression[] columns)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columns);
            return this.Insert(dataObjectList, columnNames, this.TransactionManager.DefaultTransaction);
        }

        protected virtual int Insert(System.Collections.IList dataObjectList, string[] columnNames, System.Data.IDbTransaction transaction)
        {
            System.Data.Common.DataTableMapping dataTableMapping = this.CommandBuilder.CommonCommandBuilder.GetDataTableMapping(columnNames);
            System.Data.IDbCommand command = this.CommandBuilder.GetInsertCommand(dataTableMapping, false);
            if (transaction != null)
            {
                command.Transaction = transaction;
            }
            int count = 0;
            foreach (object dataObject in dataObjectList)
            {
                SetInsertCommandParameterValues(dataObject, command);
                WriteLog(command);
                count += RaisingStudio.Data.Common.Database.ExecuteNonQueryCommand(command);
            }
            return count;
        }

  
        public virtual int Update(System.Collections.IList dataObjectList)
        {
            return this.Update(dataObjectList, this.TransactionManager.DefaultTransaction);
        }

        protected virtual int Update(System.Collections.IList dataObjectList, System.Data.IDbTransaction transaction)
        {
            System.Data.IDbCommand command = null;
            if (CacheDefalutCommand)
            {
                if (_defalutUpdateCommand == null)
                {
                    _defalutUpdateCommand = this.CommandBuilder.GetUpdateCommand(this.DefaultDataTableMapping, false, false);
                }
                command = _defalutUpdateCommand;
            }
            else
            {
                command = this.CommandBuilder.GetUpdateCommand(this.DefaultDataTableMapping, false, false);
            }
            if (transaction != null)
            {
                command.Transaction = transaction;
            }
            int count = 0;
            foreach (object dataObject in dataObjectList)
            {
                SetUpdateCommandParameterValues(dataObject, command);
                WriteLog(command);
                count += RaisingStudio.Data.Common.Database.ExecuteNonQueryCommand(command);
            }
            return count;
        }

        public virtual int Update(System.Collections.IList dataObjectList, ColumnExpression[] columns)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columns);
            return this.Update(dataObjectList, columnNames, this.TransactionManager.DefaultTransaction);
        }

        protected virtual int Update(System.Collections.IList dataObjectList, string[] columnNames, System.Data.IDbTransaction transaction)
        {
            System.Data.Common.DataTableMapping dataTableMapping = this.CommandBuilder.CommonCommandBuilder.GetDataTableMapping(columnNames);
            System.Data.IDbCommand command = this.CommandBuilder.GetUpdateCommand(dataTableMapping, false, false);
            if (transaction != null)
            {
                command.Transaction = transaction;
            }
            int count = 0;
            foreach (object dataObject in dataObjectList)
            {
                SetUpdateCommandParameterValues(dataObject, command);
                WriteLog(command);
                count += RaisingStudio.Data.Common.Database.ExecuteNonQueryCommand(command);
            }
            return count;
        }


        public virtual int Save(System.Collections.IList dataObjectList)
        {
            return this.Save(dataObjectList, this.TransactionManager.DefaultTransaction);
        }

        protected virtual int Save(System.Collections.IList dataObjectList, System.Data.IDbTransaction transaction)
        {
            System.Data.IDbCommand existsCommand = GetExistsCommand(transaction);
            System.Data.IDbCommand insertCommand = GetInsertCommand(transaction);
            System.Data.IDbCommand updateCommand = GetUpdateCommand(transaction);

            int count = 0;
            foreach (object dataObject in dataObjectList)
            {
                object[] primaryKeys = GetPrimaryKeys(dataObject);
                int i = 0;
                foreach (System.Data.IDbDataParameter parameter in existsCommand.Parameters)
                {
                    parameter.Value = primaryKeys[i];
                    i++;
                }
                WriteLog(existsCommand);
                int existsCount = Convert.ToInt32(RaisingStudio.Data.Common.Database.ExecuteScalarCommand(existsCommand));

                if (existsCount > 0)
                {
                    SetUpdateCommandParameterValues(dataObject, updateCommand);
                    WriteLog(updateCommand);
                    count += RaisingStudio.Data.Common.Database.ExecuteNonQueryCommand(updateCommand);
                }
                else
                {
                    SetInsertCommandParameterValues(dataObject, insertCommand);
                    WriteLog(insertCommand);
                    count += RaisingStudio.Data.Common.Database.ExecuteNonQueryCommand(insertCommand);
                }
            }
            return count;
        }

        private System.Data.IDbCommand GetExistsCommand(System.Data.IDbTransaction transaction)
        {
            System.Data.IDbCommand existsCommand = null;
            if (CacheDefalutCommand)
            {
                if (_defaultExistsCommand == null)
                {
                    _defaultExistsCommand = this.CommandBuilder.GetExistsCommand(this.DefaultDataTableMapping);
                }
                existsCommand = _defaultExistsCommand;
            }
            else
            {
                existsCommand = this.CommandBuilder.GetExistsCommand(this.DefaultDataTableMapping);
            }
            if (transaction != null)
            {
                existsCommand.Transaction = transaction;
            }
            return existsCommand;
        }

        private System.Data.IDbCommand GetUpdateCommand(System.Data.IDbTransaction transaction)
        {
            System.Data.IDbCommand updateCommand = null;
            if (CacheDefalutCommand)
            {
                if (_defalutUpdateCommand == null)
                {
                    _defalutUpdateCommand = this.CommandBuilder.GetUpdateCommand(this.DefaultDataTableMapping, false, false);
                }
                updateCommand = _defalutUpdateCommand;
            }
            else
            {
                updateCommand = this.CommandBuilder.GetUpdateCommand(this.DefaultDataTableMapping, false, false);
            }
            if (transaction != null)
            {
                updateCommand.Transaction = transaction;
            }
            return updateCommand;
        }

        private System.Data.IDbCommand GetInsertCommand(System.Data.IDbTransaction transaction)
        {
            System.Data.IDbCommand insertCommand = null;
            if (CacheDefalutCommand)
            {
                if (_defalutInsertCommand == null)
                {
                    _defalutInsertCommand = this.CommandBuilder.GetInsertCommand(this.DefaultDataTableMapping, false);
                }
                insertCommand = _defalutInsertCommand;
            }
            else
            {
                insertCommand = this.CommandBuilder.GetInsertCommand(this.DefaultDataTableMapping, false);
            }
            if (transaction != null)
            {
                insertCommand.Transaction = transaction;
            }
            return insertCommand;
        }


        public virtual int Save(System.Collections.IList dataObjectList, ColumnExpression[] columns)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columns);
            return this.Save(dataObjectList, columnNames, this.TransactionManager.DefaultTransaction);
        }

        protected virtual int Save(System.Collections.IList dataObjectList, string[] columnNames, System.Data.IDbTransaction transaction)
        {
            System.Data.IDbCommand existsCommand = GetExistsCommand(transaction);
            System.Data.Common.DataTableMapping dataTableMapping = this.CommandBuilder.CommonCommandBuilder.GetDataTableMapping(columnNames);
            System.Data.IDbCommand insertCommand = this.CommandBuilder.GetInsertCommand(dataTableMapping, false);
            if (transaction != null)
            {
                insertCommand.Transaction = transaction;
            }
            System.Data.IDbCommand updateCommand = this.CommandBuilder.GetUpdateCommand(dataTableMapping, false, false);
            if (transaction != null)
            {
                updateCommand.Transaction = transaction;
            }

            int count = 0;
            foreach (object dataObject in dataObjectList)
            {
                object[] primaryKeys = GetPrimaryKeys(dataObject);
                int i = 0;
                foreach (System.Data.IDbDataParameter parameter in existsCommand.Parameters)
                {
                    parameter.Value = primaryKeys[i];
                    i++;
                }
                WriteLog(existsCommand);
                int existsCount = Convert.ToInt32(RaisingStudio.Data.Common.Database.ExecuteScalarCommand(existsCommand));

                if (existsCount > 0)
                {
                    SetUpdateCommandParameterValues(dataObject, updateCommand);
                    WriteLog(updateCommand);
                    count += RaisingStudio.Data.Common.Database.ExecuteNonQueryCommand(updateCommand);
                }
                else
                {
                    SetInsertCommandParameterValues(dataObject, insertCommand);
                    WriteLog(insertCommand);
                    count += RaisingStudio.Data.Common.Database.ExecuteNonQueryCommand(insertCommand);
                }
            }
            return count;
        }
    
    
        public virtual int Exists(System.Collections.IList dataObjectList)
        {
            return this.Exists(dataObjectList, this.TransactionManager.DefaultTransaction);
        }

        protected virtual int Exists(System.Collections.IList dataObjectList, System.Data.IDbTransaction transaction)
        {
            System.Data.IDbCommand existsCommand = GetExistsCommand(transaction);

            int count = 0;
            foreach (object dataObject in dataObjectList)
            {
                object[] primaryKeys = GetPrimaryKeys(dataObject);
                int i = 0;
                foreach (System.Data.IDbDataParameter parameter in existsCommand.Parameters)
                {
                    parameter.Value = primaryKeys[i];
                    i++;
                }
                WriteLog(existsCommand);
                int existsCount = Convert.ToInt32(RaisingStudio.Data.Common.Database.ExecuteScalarCommand(existsCommand));
                if (existsCount > 0)
                {
                    count++;
                }
            }
            return count;
        }
    
    
        public virtual int Delete(System.Collections.IList dataObjectList)
        {
            return this.Delete(dataObjectList, this.TransactionManager.DefaultTransaction);
        }

        protected virtual int Delete(System.Collections.IList dataObjectList, System.Data.IDbTransaction transaction)
        {
            System.Data.IDbCommand deleteCommand = GetDeleteCommand(transaction);

            int count = 0;
            foreach (object dataObject in dataObjectList)
            {
                object[] primaryKeys = GetPrimaryKeys(dataObject);
                int i = 0;
                foreach (System.Data.IDbDataParameter parameter in deleteCommand.Parameters)
                {
                    parameter.Value = primaryKeys[i];
                    i++;
                }
                WriteLog(deleteCommand);
                int deleteCount = RaisingStudio.Data.Common.Database.ExecuteNonQueryCommand(deleteCommand);
                if (deleteCount > 0)
                {
                    count++;
                }
            }
            return count;
        }

        private System.Data.IDbCommand GetDeleteCommand(System.Data.IDbTransaction transaction)
        {
            System.Data.IDbCommand command = null;
            if (CacheDefalutCommand)
            {
                if (_defaultDeleteCommand == null)
                {
                    _defaultDeleteCommand = this.CommandBuilder.GetDeleteCommand(this.DefaultDataTableMapping, false);
                }
                command = _defaultDeleteCommand;
            }
            else
            {
                command = this.CommandBuilder.GetDeleteCommand(this.DefaultDataTableMapping, false);
            }
            return command;
        }
        #endregion



        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>data object column table.</returns>
        protected virtual IDataReader GetDataReader(System.Data.IDbTransaction transaction)
        {
            System.Data.Common.DataTableMapping dataTableMapping;
            System.Data.IDbCommand command = null;
            if (CacheDefalutCommand)
            {
                if (_defalutSelectCommand == null)
                {
                    _defalutSelectCommand = this.CommandBuilder.GetSelectCommand(out _defaultDataTableMapping);
                }
                dataTableMapping = _defaultDataTableMapping;
                command = _defalutSelectCommand;
            }
            else
            {
                command = this.CommandBuilder.GetSelectCommand(out dataTableMapping); ;
            }
#if !(PocketPC || Smartphone || WindowsCE)
            if (this.DatabaseType == DatabaseType.SHAREPOINT)
            {
                (command as System.Data.SharePoint.SharePointCommand).ListUrl = dataTableMapping.SourceTable;
            }
#endif
            if (transaction != null)
            {
                command.Transaction = transaction;
            }
            WriteLog(command);
            return RaisingStudio.Data.Common.Database.ExecuteReaderCommand(command);
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>data object column table.</returns>
        protected virtual IDataReader GetDataReader(string[] columnNames, System.Data.IDbTransaction transaction)
        {
            System.Data.Common.DataTableMapping dataTableMapping;
            System.Data.IDbCommand command = this.CommandBuilder.GetSelectCommand(columnNames, out dataTableMapping);
#if !(PocketPC || Smartphone || WindowsCE)
            if (this.DatabaseType == DatabaseType.SHAREPOINT)
            {
                (command as System.Data.SharePoint.SharePointCommand).ListUrl = dataTableMapping.SourceTable;
            }
#endif
            if (transaction != null)
            {
                command.Transaction = transaction;
            }
            WriteLog(command);
            return RaisingStudio.Data.Common.Database.ExecuteReaderCommand(command);
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <returns>data object column table.</returns>
        public virtual IDataReader GetDataReader()
        {
            return GetDataReader(this.TransactionManager.DefaultTransaction);
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <returns>data object column table.</returns>
        public virtual IDataReader GetDataReader(string[] columnNames)
        {
            return GetDataReader(columnNames, this.TransactionManager.DefaultTransaction);
        }


        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>data object column table.</returns>
        protected virtual IDataReader GetDataReader(CommonCommand conditionCommand, System.Data.IDbTransaction transaction)
        {
            System.Data.Common.DataTableMapping dataTableMapping;
            System.Data.IDbCommand command = this.CommandBuilder.GetSelectCommand(conditionCommand, out dataTableMapping);
#if !(PocketPC || Smartphone || WindowsCE)
            if (this.DatabaseType == DatabaseType.SHAREPOINT)
            {
                (command as System.Data.SharePoint.SharePointCommand).ListUrl = dataTableMapping.SourceTable;
            }
#endif
            if (transaction != null)
            {
                command.Transaction = transaction;
            }
            WriteLog(command);
            return RaisingStudio.Data.Common.Database.ExecuteReaderCommand(command);
        }


        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="conditionExpression">Condition expression</param>
        /// <returns>data object column table.</returns>
        public virtual IDataReader GetDataReader(RaisingStudio.Data.Expressions.ConditionExpression conditionExpression)
        {
            RaisingStudio.Data.Common.Builders.Expressions.ConditionExpressionCommandBuilder conditionExpressionCommandBuilder = CreateConditionExpressionCommandBuilder(conditionExpression);
            CommonCommand conditionCommand = conditionExpressionCommandBuilder.GetExpressionCommand();
            return GetDataReader(conditionCommand, this.TransactionManager.DefaultTransaction);
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>data object column table.</returns>
        protected virtual IDataReader GetDataReader(string[] columnNames, CommonCommand conditionCommand, System.Data.IDbTransaction transaction)
        {
            System.Data.Common.DataTableMapping dataTableMapping;
            System.Data.IDbCommand command = this.CommandBuilder.GetSelectCommand(columnNames, conditionCommand, out dataTableMapping);
            if (transaction != null)
            {
                command.Transaction = transaction;
            }
            WriteLog(command);
            return RaisingStudio.Data.Common.Database.ExecuteReaderCommand(command);
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionExpression">Condition expression</param>
        /// <returns>data object column table.</returns>
        public virtual IDataReader GetDataReader(string[] columnNames, RaisingStudio.Data.Expressions.ConditionExpression conditionExpression)
        {
            RaisingStudio.Data.Common.Builders.Expressions.ConditionExpressionCommandBuilder conditionExpressionCommandBuilder = CreateConditionExpressionCommandBuilder(conditionExpression);
            CommonCommand conditionCommand = conditionExpressionCommandBuilder.GetExpressionCommand();
            return GetDataReader(columnNames, conditionCommand, this.TransactionManager.DefaultTransaction);
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <param name="conditionExpression">Condition expression</param>
        /// <returns>data object column table.</returns>
        public virtual IDataReader GetDataReader(ColumnExpression[] columnExpressions, RaisingStudio.Data.Expressions.ConditionExpression conditionExpression)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return GetDataReader(columnNames, conditionExpression);
        }

        /// <summary>
        /// Gets data object column table.
        /// </summary>
        /// <param name="columnExpressions">An array of column expressions.</param>
        /// <returns>data object column table.</returns>
        public virtual IDataReader GetDataReader(ColumnExpression[] columnExpressions)
        {
            string[] columnNames = ConditionExpressionCommandBuilder.GetColumnNamesFromColumnExpressions(columnExpressions);
            return GetDataReader(columnNames);
        }
    }
}
